Annotation of loncom/interface/loncoursequeueadmin.pm, revision 1.63

1.1       raeburn     1: # The LearningOnline Network
1.19      raeburn     2: # Utilities to administer domain course requests and course self-enroll requests
1.1       raeburn     3: #
1.63    ! raeburn     4: # $Id: loncoursequeueadmin.pm,v 1.62 2021/11/24 04:25:02 raeburn Exp $
1.1       raeburn     5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
                     21: # along with LON-CAPA; if not, write to the Free Software
                     22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     23: #
                     24: # /home/httpd/html/adm/gpl.txt
                     25: #
                     26: # http://www.lon-capa.org/
                     27: #
                     28: ###
                     29: 
1.23      raeburn    30: =pod
                     31: 
1.1       raeburn    32: =head1 NAME
                     33: 
                     34: Apache::loncoursequeueadmin.pm
                     35: 
                     36: =head1 SYNOPSIS
                     37: 
1.14      raeburn    38: Utilities used by domain coordinators to administer queued course creation requests,
                     39: and by course coordinators for queued self-enrollment requests, and by general
                     40: users to display their queued self-enrollment requests.  
1.1       raeburn    41: 
                     42: This is part of the LearningOnline Network with CAPA project
                     43: described at http://www.lon-capa.org.
                     44: 
                     45: =head1 SUBROUTINES
                     46: 
                     47: =over
                     48: 
                     49: =item send_selfserve_notification()
                     50: 
                     51: =item display_queued_requests()
                     52: 
1.23      raeburn    53: =item build_queue_display()
                     54: 
1.1       raeburn    55: =item update_request_queue()
                     56: 
                     57: =item get_student_counts()
                     58: 
1.13      raeburn    59: =item course_creation()
                     60: 
                     61: =item build_batchcreatehash()
                     62:  
                     63: =item can_clone_course()
                     64: 
                     65: =item get_processtype()
                     66: 
1.14      raeburn    67: =item queued_selfenrollment()
                     68: 
1.23      raeburn    69: =item update_coursereq_status()
                     70: 
                     71: =item process_official_reqs()
                     72: 
1.31      raeburn    73: =item is_active_author()
                     74: 
                     75: =item author_prompt()
                     76: 
                     77: =item reqauthor_check()
                     78: 
                     79: =item process_reqauthor()
                     80: 
1.1       raeburn    81: =back
                     82: 
                     83: =cut
                     84: 
                     85: package Apache::loncoursequeueadmin;
                     86: 
                     87: use strict;
                     88: use Apache::lonnet;
                     89: use Apache::loncommon;
                     90: use Apache::lonmsg;
                     91: use Apache::lonlocal;
1.2       raeburn    92: use Apache::lonuserutils;
1.45      raeburn    93: use LONCAPA::batchcreatecourse;
1.19      raeburn    94: use LONCAPA qw(:DEFAULT :match);
1.1       raeburn    95: 
                     96: sub send_selfserve_notification {
1.2       raeburn    97:     my ($notifylist,$textstr,$cid,$contextdesc,$timestamp,$context,$sender,
1.12      raeburn    98:         $approvedlist,$rejectedlist,$crstype) = @_;
1.1       raeburn    99: # FIXME locallocaltime needs to be able to take $sender_lh as an argument
                    100: #       so this can be localized to the recipients date display format/time zone
                    101:     $timestamp =&Apache::lonlocal::locallocaltime($timestamp);
1.26      raeburn   102:     my ($msgcc,$rawsubj,@rawmsg,$subject,$message,$reviewer,$msgtxt);
                    103:     my ($senderuname,$senderudom) = split(':',$sender);
1.1       raeburn   104:     if ($context eq 'coursemanagers') {
                    105:         $rawsubj = 'Self-enrollment requests processed';
                    106:         push(@rawmsg,{
1.10      raeburn   107:                       mt => 'Enrollment requests in the following course: [_1] have been processed.',
1.57      raeburn   108:                       args => ["\n$contextdesc\n"],
1.1       raeburn   109:                      });
                    110:     } elsif ($context eq 'domainmanagers') {
1.12      raeburn   111:         $rawsubj = 'Course/Community requests reviewed';
1.1       raeburn   112:         push(@rawmsg,{
1.57      raeburn   113:                       mt  => 'Course/Community creation requests in the following domain: [_1] have been reviewed.',
                    114:                       args => ["\n$contextdesc\n"],
1.30      raeburn   115:                      });
                    116:         if (ref($textstr) eq 'ARRAY') {
                    117:             push(@rawmsg,@{$textstr});
                    118:         }
                    119:     } elsif ($context eq 'authormanagers') {
1.42      bisitz    120:         $rawsubj = 'Authoring Space requests reviewed';
1.30      raeburn   121:         push(@rawmsg,{
1.57      raeburn   122:                       mt  => 'Authoring requests in the following domain: [_1] have been reviewed.',
                    123:                       args => ["\n$contextdesc\n"],
1.1       raeburn   124:                      });
                    125:         if (ref($textstr) eq 'ARRAY') {
                    126:             push(@rawmsg,@{$textstr});
                    127:         }
1.43      raeburn   128:     } elsif ($context eq 'usernamemanagers') {
                    129:         $rawsubj = 'LON-CAPA account requests reviewed';
                    130:         push(@rawmsg,{
1.57      raeburn   131:                       mt  => 'Account requests in the following domain: [_1] have been reviewed.',
                    132:                       args => ["\n$contextdesc\n"],
1.43      raeburn   133:                      });
                    134:         if (ref($textstr) eq 'ARRAY') {
                    135:             push(@rawmsg,@{$textstr});
                    136:         }
1.1       raeburn   137:     } elsif ($context eq 'enroller') {
                    138:         $rawsubj = 'Enrollment request';
1.12      raeburn   139:         if ($crstype eq 'community') {
                    140:             $msgtxt = 'Your request for enrollment in the following community: [_1]requested on [_2]has been reviewed by a Coordinator.'
                    141:         } else {
                    142:             $msgtxt = 'Your request for enrollment in the following course: [_1]requested on [_2]has been reviewed by a Course Coordinator.';
                    143:         } 
1.1       raeburn   144:         push(@rawmsg,{
1.12      raeburn   145:                       mt  => $msgtxt,
1.2       raeburn   146:                       args => ["\n  ".$contextdesc.",\n",$timestamp.",\n"],
1.1       raeburn   147:                      });
                    148:         if (ref($textstr) eq 'ARRAY') {
                    149:             push(@rawmsg,@{$textstr});
                    150:         }
                    151:     } elsif ($context eq 'courserequestor') {
1.12      raeburn   152:         if ($crstype eq 'Community') {
                    153:             $rawsubj = 'Community request';
                    154:             $msgtxt = 'Your request for creation of the following community: [_1]requested on [_2]has been reviewed by a Domain Coordinator.';
                    155:         } else {
                    156:             $rawsubj = 'Course request';
                    157:             $msgtxt = 'Your request for creation of the following course: [_1]requested on [_2]has been reviewed by a Domain Coordinator.';
                    158:         }
1.1       raeburn   159:         push(@rawmsg,{
1.12      raeburn   160:                       mt  => $msgtxt,
1.2       raeburn   161:                       args => ["\n".$contextdesc.",\n",$timestamp.",\n"],
1.1       raeburn   162: 
                    163:                      });
                    164:         if (ref($textstr) eq 'ARRAY') {
                    165:             push(@rawmsg,@{$textstr});
                    166:         }
1.26      raeburn   167:     } elsif ($context eq 'pendingrequestor') {
                    168:         if ($crstype eq 'Community') {
                    169:             $rawsubj = 'Community request';
                    170:         } else {
                    171:             $rawsubj = 'Processed course request';
                    172:         }
                    173:         if (ref($textstr) eq 'ARRAY') {
                    174:             push(@rawmsg,@{$textstr});
                    175:         }
1.1       raeburn   176:     } elsif ($context eq 'coursereq') {
1.12      raeburn   177:         if ($crstype eq 'community') {
                    178:             $rawsubj = 'Community request to review';
                    179:             $msgtxt = 'Creation of the following community: [_1]was requested by [_2] on [_3].';
                    180:         } else {
                    181:             $rawsubj = 'Course request to review';
                    182:             $msgtxt = 'Creation of the following course: [_1]was requested by [_2] on [_3].';
                    183:         }
1.1       raeburn   184:         push(@rawmsg,{
1.12      raeburn   185:                       mt  => $msgtxt,
1.2       raeburn   186:                       args => ["\n  $contextdesc\n",$textstr,$timestamp],
1.1       raeburn   187:                      },
                    188:                      {
1.12      raeburn   189:                       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.',
1.31      raeburn   190:                       args => ["\n","\n\n","\n\n"],
1.1       raeburn   191:                      });
                    192:     } elsif ($context eq 'selfenrollreq') {
                    193:         $rawsubj = 'Self-enrollment request';
1.12      raeburn   194:         if ($crstype eq 'community') {
1.31      raeburn   195:             $msgtxt = 'Enrollment in the following community: [_1]was requested by [_2] on [_3].'
1.12      raeburn   196:         } else {
1.31      raeburn   197:             $msgtxt = 'Enrollment in the following course: [_1]was requested by [_2] on [_3].'
1.12      raeburn   198:         }
1.1       raeburn   199:         push(@rawmsg,{
1.12      raeburn   200:                       mt  => $msgtxt,
1.2       raeburn   201:                       args => ["\n  $contextdesc\n",$textstr,$timestamp."\n"],
                    202:                      });
1.12      raeburn   203:         my $directions;  
                    204:         if ($crstype eq 'community') {
                    205:             $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.';
1.2       raeburn   206:         } else {
1.12      raeburn   207:             $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.';
                    208:         }
                    209:         push(@rawmsg,
1.1       raeburn   210:                      {
1.12      raeburn   211:                       mt   => $directions,
1.2       raeburn   212:                       args => ["  \n\n","\n"],
1.1       raeburn   213:                      });
1.30      raeburn   214:     } elsif ($context eq 'authorreq') {
1.42      bisitz    215:         $rawsubj = 'Authoring Space request to review';
1.31      raeburn   216:         $msgtxt = 'Assignment of an author role in the [_1] domain[_2]was requested by [_3] on [_4].';
1.30      raeburn   217:         push(@rawmsg,{
                    218:                       mt  => $msgtxt,
                    219:                       args => [$contextdesc,"\n",$textstr,$timestamp],
                    220:                      },
                    221:                      {
1.42      bisitz    222:                       mt =>'[_1]As Domain Coordinator, use: [_2]Main Menu -> Create users or modify the roles and privileges of users -> Authoring Space requests[_3]to display a list of pending requests, which you can either approve or reject.',
1.30      raeburn   223:                       args => ["\n","\n\n  ","\n\n"],
                    224:                      });
                    225:     } elsif ($context eq 'requestauthor') {
1.42      bisitz    226:         $rawsubj = 'Authoring Space request';
                    227:         $msgtxt = 'Your request for an Authoring Space requested on [_1]has been reviewed by a Domain Coordinator.';
1.30      raeburn   228:         push(@rawmsg,{
                    229:                       mt  => $msgtxt,
                    230:                       args => [$timestamp."\n"],
                    231:                      });
                    232:         if (ref($textstr) eq 'ARRAY') {
                    233:             push(@rawmsg,@{$textstr});
                    234:         }
1.43      raeburn   235:     } elsif ($context eq 'usernamereq') {
                    236:         $rawsubj = 'LON-CAPA account request';
                    237:         $msgtxt = 'Creation of a LON-CAPA account in the [_1] domain[_2]was requested by [_3] on [_4].';
                    238:         push(@rawmsg,{
                    239:                       mt  => $msgtxt,
                    240:                       args => [$contextdesc,"\n",$textstr,$timestamp],
                    241:                      },
                    242:                      {
                    243:                       mt =>'[_1]As Domain Coordinator, use: [_2]Main Menu -> Create users or modify the roles and privileges of users
                    244:  -> LON-CAPA account requests[_3]to display a list of pending requests, which you can either approve or reject.',
                    245:                       args => ["\n","\n\n  ","\n\n"],
                    246:                      });
                    247:     } elsif ($context eq 'requestusername') {
                    248:         $rawsubj = 'LON-CAPA account request';
                    249:         $msgtxt = 'Your request for a LON-CAPA account requested on [_1]has been reviewed by a Domain Coordinator.';
                    250:         push(@rawmsg,{
                    251:                       mt  => $msgtxt,
                    252:                       args => [$timestamp."\n"],
                    253:                      });
                    254:         if (ref($textstr) eq 'ARRAY') {
                    255:             push(@rawmsg,@{$textstr});
                    256:         }
1.39      raeburn   257:     } elsif ($context eq 'uniquecode') {
                    258:         $rawsubj = 'Course Identifier';
                    259:         if (ref($textstr) eq 'ARRAY') {
                    260:             push(@rawmsg,@{$textstr});
                    261:         }
1.41      raeburn   262:     } elsif ($context eq 'queuedcrsreq') {
                    263:         $rawsubj = 'Course Request Queued';
                    264:         if (ref($textstr) eq 'ARRAY') {
                    265:             push(@rawmsg,@{$textstr});
                    266:         }
                    267:     } elsif ($context eq 'createdcrsreq') {
                    268:         $rawsubj = 'Course Creation Information';
                    269:         if (ref($textstr) eq 'ARRAY') {
                    270:             push(@rawmsg,@{$textstr});
                    271:         }
1.63    ! raeburn   272:     } elsif ($context eq 'othdomroleuser') {
        !           273:         my $linktext = 'Roles';
        !           274:         if (&Apache::loncommon::show_course()) {
        !           275:             $linktext = 'Courses';
        !           276:         }
        !           277:         $rawsubj = 'Role Assignment Approval';
        !           278:         push(@rawmsg,{
        !           279:                       mt  => 'A domain different to your own LON-CAPA domain ([_1]) wants to assign you a role in their domain.',
        !           280:                       args => ["\n$contextdesc\n"],
        !           281:                      },
        !           282:                      {
        !           283:                       mt =>"[_1]Click $linktext at top right, then click 'Manage Role Requests' in the gray Functions bar ".
        !           284:                            "to display a list of pending role assignments in other domain(s), which you can either accept or reject.",
        !           285:                       args => ["\n\n"],
        !           286:                      });
        !           287:     } elsif ($context eq 'othdomroledc') {
        !           288:         $rawsubj = 'Role Assignment Authorization';
        !           289:         push(@rawmsg,{
        !           290:                       mt  => 'Another LON-CAPA domain wants to assign a role in their domain to a user from your domain.',
        !           291:                       args => [],
        !           292:                      },
        !           293:                      {
        !           294:                       mt =>'[_1]As Domain Coordinator, use: [_2]Main Menu -> Create users or modify the roles and privileges of users
        !           295:  -> Queued Role Assignments (this domain) [_3]to display a list of pending requests, which you can either approve or reject.',
        !           296:                       args => ["\n","\n\n  ","\n\n"],
        !           297:                      });
1.1       raeburn   298:     }
                    299:     my @to_notify = split(/,/,$notifylist);
                    300:     my $numsent = 0;
                    301:     my @recusers;
                    302:     my @recudoms;
                    303:     foreach my $cc (@to_notify) {
                    304:         my ($ccname,$ccdom) = split(/:/,$cc);
                    305:         if (!exists($msgcc->{$ccname.':'.$ccdom})) {
                    306:             push(@recusers,$ccname);
                    307:             push(@recudoms,$ccdom);
                    308:             $msgcc->{$ccname.':'.$ccdom}='';
                    309:             $numsent ++;
                    310:         }
                    311:     }
                    312:     my %reciphash = (
                    313:                      cc => $msgcc,
                    314:     );
1.43      raeburn   315:     my ($uname,$udom,$need_temp_env);
1.1       raeburn   316:     if ($sender =~ /:/) {
                    317:         ($uname,$udom) = split(/:/,$sender);
1.43      raeburn   318:         if ($context eq 'usernamereq') {
                    319:             unless ($env{'user.name'} && $env{'user.domain'}) {
                    320:                 $need_temp_env = 1;
                    321:             }
                    322:         }
1.2       raeburn   323:     } elsif ($context eq 'course') {
1.1       raeburn   324:         $uname = $sender;
                    325:         my %courseinfo = &Apache::lonnet::coursedescription($cid);
                    326:         $udom = $courseinfo{'num'};
                    327:     }
                    328:     my %sentmessage;
                    329:     my $stamp = time;
                    330:     my $msgcount = &Apache::lonmsg::get_uniq();
                    331:     my $sender_lh = &Apache::loncommon::user_lang($uname,$udom,$cid);
1.59      raeburn   332:     $subject = &mt_user($sender_lh,$rawsubj);
1.1       raeburn   333:     $message = '';
                    334:     foreach my $item (@rawmsg) {
                    335:         if (ref($item) eq 'HASH') {
1.59      raeburn   336:             $message .= &mt_user($sender_lh,$item->{mt},@{$item->{args}})."\n";
1.1       raeburn   337:         }
                    338:     }
1.43      raeburn   339:     &Apache::lonmsg::process_sent_mail($subject,'',$numsent,$stamp,$uname,$udom,$msgcount,$cid,$$,$message,
                    340:                                        \@recusers,\@recudoms,undef,undef,undef,undef,$senderuname,$senderudom);
1.1       raeburn   341:     my ($recipid,$recipstatus) = &Apache::lonmsg::store_recipients($subject,$uname,$udom,\%reciphash);
                    342:     my $status;
1.43      raeburn   343:     if ($need_temp_env) {
                    344:         $env{'user.name'} = $uname;
                    345:         $env{'user.domain'} = $udom;
                    346:     }
1.1       raeburn   347:     foreach my $recip (sort(keys(%{$msgcc}))) {
                    348:         my ($ccname,$ccdom) = split(/:/,$recip);
                    349:         my $recip_lh = &Apache::loncommon::user_lang($ccname,$ccdom,$cid);
1.59      raeburn   350:         my $subject = &mt_user($sender_lh,$rawsubj);
1.1       raeburn   351:         my $message = '';
                    352:         foreach my $item (@rawmsg) {
                    353:             if (ref($item) eq 'HASH') {
1.59      raeburn   354:                 $message .= &mt_user($sender_lh,$item->{mt},
                    355:                                      @{$item->{args}})."\n";
1.1       raeburn   356:             }
                    357:         }
1.10      raeburn   358:         if ($context eq 'coursemanagers') {
1.1       raeburn   359:             if ($approvedlist) {
1.59      raeburn   360:                 $message .= "\n\n".&mt_user($sender_lh,'Approved enrollments:')."\n".$approvedlist;
1.1       raeburn   361:             }
                    362:             if ($rejectedlist) {
1.59      raeburn   363:                 $message .= "\n\n".&mt_user($sender_lh,'Rejected enrollments:')."\n".$rejectedlist;
1.1       raeburn   364:             }
                    365:         } elsif ($context eq 'domainmanagers') {
                    366:             if ($approvedlist) {
1.59      raeburn   367:                 $message .= "\n\n".&mt_user($sender_lh,'Approved course requests:')."\n".$approvedlist;
1.1       raeburn   368:             }
                    369:             if ($rejectedlist) {
1.59      raeburn   370:                 $message .= "\n\n".&mt_user($sender_lh,'Rejected course requests:')."\n".$rejectedlist;
1.1       raeburn   371:             }
1.30      raeburn   372:         } elsif ($context eq 'authormanagers') {
                    373:             if ($approvedlist) {
1.59      raeburn   374:                 $message .= "\n\n".&mt_user($sender_lh,'Approved author role requests:')."\n".$approvedlist;
1.30      raeburn   375:             }
                    376:             if ($rejectedlist) {
1.59      raeburn   377:                 $message .= "\n\n".&mt_user($sender_lh,'Rejected author role requests:')."\n".$rejectedlist;
1.30      raeburn   378:             }
1.43      raeburn   379:         } elsif ($context eq 'usernamemanagers') {
                    380:             if ($approvedlist) {
1.59      raeburn   381:                 $message .= "\n\n".&mt_user($sender_lh,'Approved LON-CAPA account requests:')."\n".$approvedlist;
1.43      raeburn   382:             }
                    383:             if ($rejectedlist) {
1.59      raeburn   384:                 $message .= "\n\n".&mt_user($sender_lh,'Rejected LON-CAPA account requests:')."\n".$rejectedlist;
1.43      raeburn   385:             }
1.1       raeburn   386:         }
1.43      raeburn   387:         $status .= &Apache::lonmsg::user_normal_msg($ccname,$ccdom,$subject,$message,undef,undef,undef,1,
                    388:                                                     \%sentmessage,undef,undef,undef,1,$recipid).',';
1.1       raeburn   389:     }
                    390:     $status =~ s/,$//;
1.43      raeburn   391:     if ($need_temp_env) {
                    392:         undef($env{'user.name'});
                    393:         undef($env{'user.domain'});
                    394:     }
1.1       raeburn   395:     return ($recipstatus,$status);
                    396: }
                    397: 
                    398: sub display_queued_requests {
1.63    ! raeburn   399:     my ($context,$dom,$cnum,$secondary) = @_;
1.2       raeburn   400:     my ($namespace,$formaction,$nextelement,%requesthash);
1.1       raeburn   401:     if ($context eq 'course') {
                    402:         $formaction = '/adm/createuser';
                    403:         $namespace = 'selfenrollrequests';
                    404:         %requesthash = &Apache::lonnet::dump($namespace,$dom,$cnum);
1.2       raeburn   405:         $nextelement = '<input type="hidden" name="state" value="done" />';
1.30      raeburn   406:     } elsif ($context eq 'requestauthor') {
                    407:         $formaction = '/adm/createuser';
                    408:         $namespace = 'requestauthorqueue';
                    409:         %requesthash = &Apache::lonnet::dump_dom($namespace,$dom);
                    410:         $nextelement = '<input type="hidden" name="state" value="done" />';
1.43      raeburn   411:     } elsif ($context eq 'requestusername') {
                    412:         $formaction = '/adm/createuser';
                    413:         $namespace = 'usernamequeue';
                    414:         %requesthash = &Apache::lonnet::dump_dom($namespace,$dom);
                    415:         $nextelement = '<input type="hidden" name="state" value="done" />';
1.63    ! raeburn   416:     } elsif ($context eq 'othdomqueue') {
        !           417:         $formaction = '/adm/createuser';
        !           418:         $namespace = 'othdomqueued';
        !           419:         if ($secondary eq 'domain') {
        !           420:             %requesthash = &Apache::lonnet::dump_dom($namespace,$dom);
        !           421:             foreach my $key (keys(%requesthash)) {
        !           422:                 delete($requesthash{$key}) if ($key =~ /:(ca|aa)$/);
        !           423:             }
        !           424:         } elsif ($secondary eq 'author') {
        !           425:             %requesthash = &Apache::lonnet::dump($namespace,$dom,$cnum);
        !           426:             if ($cnum eq &Apache::lonnet::get_domainconfiguser($dom)) {
        !           427:                 foreach my $key (keys(%requesthash)) {
        !           428:                     delete($requesthash{$key}) if ($key !~ /:(ca|aa)$/);
        !           429:                 }
        !           430:             }
        !           431:         } else {
        !           432:             %requesthash = &Apache::lonnet::dump($namespace,$dom,$cnum);
        !           433:         }
        !           434:     } elsif ($context eq 'othdomaction') {
        !           435:         $formaction = '/adm/createuser';
        !           436:         $namespace = 'queuedrolereqs';
        !           437:         if ($secondary eq 'domain') {
        !           438:             my $confname = &Apache::lonnet::get_domainconfiguser($dom);
        !           439:             %requesthash = &Apache::lonnet::dump($namespace,$dom,$confname);
        !           440:         } else {
        !           441:             %requesthash = &Apache::lonnet::dump($namespace,$dom,$cnum);
        !           442:         }
        !           443:         $nextelement = '<input type="hidden" name="state" value="done" />';
1.1       raeburn   444:     } else {
                    445:         $formaction = '/adm/createcourse';
                    446:         $namespace = 'courserequestqueue';
1.23      raeburn   447:         my $disposition = 'approval';
1.24      raeburn   448:         my $nextphase = 'requestchange';
1.23      raeburn   449:         if ($context eq 'pending') {
                    450:             $disposition = 'pending';
1.24      raeburn   451:             $nextphase = 'requestvalidation';
1.56      raeburn   452:         } elsif ($context eq 'displaypending') {
                    453:             $disposition = 'pending';
1.23      raeburn   454:         }
                    455:         %requesthash = &Apache::lonnet::dump_dom($namespace,$dom,'_'.$disposition);
1.24      raeburn   456:         $nextelement = '<input type="hidden" name="phase" value="'.$nextphase.'" />';
1.1       raeburn   457:     }
1.23      raeburn   458:     my ($output,%queue_by_date);
1.1       raeburn   459:     if (keys(%requesthash) > 0) {
1.2       raeburn   460:         $output = '<form method="post" name="changequeue" action="'.$formaction.'" />'."\n".
                    461:                   '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />'."\n".
1.23      raeburn   462:                   $nextelement."\n";
1.1       raeburn   463:         foreach my $item (keys(%requesthash)) {
1.23      raeburn   464:             my ($timestamp,$entry,$pending);
1.1       raeburn   465:             if ($context eq 'course') {
                    466:                 ($timestamp, my $usec) = split(/:/,$requesthash{$item});
                    467:                 $entry = $item.':'.$usec;
1.30      raeburn   468:             } elsif ($context eq 'requestauthor') {
                    469:                 $timestamp = $requesthash{$item};
                    470:                 ($entry) = ($item =~ /^($match_username)_approval$/);
1.43      raeburn   471:             } elsif ($context eq 'requestusername') {
                    472:                 $timestamp = $requesthash{$item};
                    473:                 ($entry) = (&unescape($item) =~ /^($match_username)_approval$/);
1.63    ! raeburn   474:             } elsif ($context eq 'othdomqueue') {
        !           475:                 if (ref($requesthash{$item}) eq 'HASH') {
        !           476:                     my ($puname,$pudom,$prole,$psec) = split(/:/,$item);
        !           477:                     $timestamp = $requesthash{$item}{'timestamp'};
        !           478:                     my $adj = $requesthash{$item}{'adj'};
        !           479:                     $entry = join(':',$puname,$pudom,$prole,$adj,
        !           480:                                       &escape($requesthash{$item}{'requester'}),
        !           481:                                       $psec);
        !           482:                 }
        !           483:             } elsif ($context eq 'othdomaction') {
        !           484:                if (ref($requesthash{$item}) eq 'HASH') {
        !           485:                    $timestamp = $requesthash{$item}{'timestamp'};
        !           486:                    $entry = &escape($item).':'.&escape($requesthash{$item}{'requester'});
        !           487:                }
1.1       raeburn   488:             } else {
                    489:                 if (ref($requesthash{$item}) eq 'HASH') {
1.63    ! raeburn   490:                     $timestamp = $requesthash{$item}{'timestamp'};
1.2       raeburn   491:                     my ($cnum,$disposition) = split('_',$item);
                    492:                     $entry = $cnum.':'.$requesthash{$item}{'ownername'}.':'.
1.23      raeburn   493:                              $requesthash{$item}{'ownerdom'}.':';
1.56      raeburn   494:                     if (($context eq 'pending') || ($context eq 'displaypending')) {
1.23      raeburn   495:                         $entry .= $requesthash{$item}{'instcode'};
                    496:                     } else {
                    497:                         $entry .= $requesthash{$item}{'crstype'};
                    498:                     }
                    499:                     $entry .= ':'.$requesthash{$item}{'description'};
1.1       raeburn   500:                 }
                    501:             }
                    502:             if ($entry ne '') {
1.23      raeburn   503:                 if (ref($queue_by_date{$timestamp}) eq 'ARRAY') {
                    504:                     push(@{$queue_by_date{$timestamp}},$entry);
1.1       raeburn   505:                 } else {
1.23      raeburn   506:                     $queue_by_date{$timestamp} = [$entry];
1.1       raeburn   507:                 }
                    508:             }
                    509:         }
1.23      raeburn   510:         if (keys(%queue_by_date) > 0) {
                    511:             if ($context eq 'course') {
                    512:                 $output .=  '<h3>'.&mt('Self-enrollment requests queued pending approval by a Coordinator').'</h3>';
1.56      raeburn   513:             } elsif (($context eq 'pending') || ($context eq 'displaypending')) {
1.23      raeburn   514:                 $output .= '<h3>'.&mt('Requests for official courses queued pending validation').'</h3>'.
                    515:                            '<p>'.&mt('Requests are validated against institutional data to confirm that the requestor is an instructor of record.').'<br />'.
1.56      raeburn   516:                            &mt('Validation is attempted when the request is submitted.').' '.
                    517:                            &mt('If unvalidated, the request will be held in a queue.').' '.
                    518:                            &mt('Validation of pending requests is automatically repeated daily.').'</p>';
1.30      raeburn   519:             } elsif ($context eq 'requestauthor') {
1.42      bisitz    520:                 $output .= '<h3>'.&mt('Requests for Authoring Space queued pending approval by a Domain Coordinator').'</h3>';
1.43      raeburn   521:             } elsif ($context eq 'requestusername') {
                    522:                 $output .= '<h3>'.&mt('Requests for LON-CAPA accounts queued pending approval by a Domain Coordinator').'</h3>';
1.63    ! raeburn   523:             } elsif ($context eq 'othdomqueue') {
        !           524:                 if ($secondary eq 'domain') {
        !           525:                     $output .= '<h3>'.&mt('Domain role assignments for users from another domain, queued pending approval').'</h3>';
        !           526:                 } elsif ($secondary eq 'author') {
        !           527:                     $output .= '<h3>'.&mt('Co-author role assignments for users from another domain, queued pending approval').'</h3>';
        !           528:                 } elsif ($secondary eq 'course') {
        !           529:                     $output .= '<h3>'.&mt('Course role assignments for users from another domain, queued pending approval').'</h3>';
        !           530:                 } elsif ($secondary eq 'community') {
        !           531:                     $output .= '<h3>'.&mt('Community role assignments for users from another domain, queued pending approval').'</h3>';
        !           532:                 }
        !           533:             } elsif ($context eq 'othdomaction') {
        !           534:                 if ($secondary eq 'user') {
        !           535:                     $output .= '<h3>'.&mt('Role assignments for you in other domains, queued pending your acceptance of the role.').'</h3>';
        !           536:                 } elsif ($secondary eq 'domain') {
        !           537:                     $output .= '<h3>'.&mt('Role assignments in other domains, queued pending domain coordinator approval in this domain.').'</h3>';
        !           538:                 }
1.23      raeburn   539:             } else {
1.30      raeburn   540:                 $output .= '<h3>'.&mt('Course/Community requests queued pending approval by a Domain Coordinator').'</h3>';
1.23      raeburn   541:             } 
1.63    ! raeburn   542:             $output .= &build_queue_display($dom,$context,\%queue_by_date,$secondary).
1.23      raeburn   543:                        '<input type="hidden" name="queue" value="approval" />';
                    544:         } else {
                    545:             $output .= '<div class="LC_info">';
                    546:             if ($context eq 'course') {
                    547:                 $output .= &mt('There are currently no enrollment requests awaiting approval.');
                    548:             } elsif ($context eq 'pending') {
                    549:                 $output .= &mt('There are currently no requests for official courses awaiting validation.');
1.30      raeburn   550:             } elsif ($context eq 'requestauthor') {
1.42      bisitz    551:                 $output .= &mt('There are currently no requests for Authoring Space awaiting approval.');
1.43      raeburn   552:             } elsif ($context eq 'requestusername') {
                    553:                 $output .= &mt('There are currently no requests for LON-CAPA accounts awaiting approval.');
1.23      raeburn   554:             } elsif ($context eq 'domain') {
                    555:                 $output .= &mt('There are currently no course or community requests awaiting approval.');
1.63    ! raeburn   556:             } elsif ($context eq 'othdomqueue') {
        !           557:                 if ($secondary eq 'domain') {
        !           558:                     $output .= &mt('There are currently no domain role assignment(s) for user(s) from another domain queued pending approval');
        !           559:                 } elsif ($secondary eq 'author') {
        !           560:                     $output .= &mt('There are currently no co-author role assignment(s) for user(s) from another domain queued pending approval');
        !           561:                 } elsif ($secondary eq 'course') {
        !           562:                     $output .= &mt('There are currently no course role assignment(s) for user(s) from another domain queued pending approval');
        !           563:                 } elsif ($secondary eq 'community') {
        !           564:                     $output .= &mt('There are currently no community role assignment(s) for user(s) from another domain queued pending approval');
        !           565:                 }
        !           566:             } elsif ($context eq 'othdomaction') {
        !           567:                 if ($secondary eq 'user') {
        !           568:                     $output .= &mt('There are currently no pending role assignments for you in other domains, queued pending your acceptance of the role.');
        !           569:                 } elsif ($secondary eq 'domain') {
        !           570:                     $output .= &mt('There are currently no pending role assignments in other domains, queued pending domain coordinator approval in this domain.');
        !           571:                 }
1.23      raeburn   572:             }
1.63    ! raeburn   573:             $output .= '</div>';
1.23      raeburn   574:         }
                    575:         if ($context eq 'pending') {
1.24      raeburn   576:             $output .= '<br /><input type="submit" name="validationcheck" value="'.
                    577:                        &mt('Validate').'" /><br />'."\n".
1.56      raeburn   578:                        '<p>'.&mt('Any course/community requests which are successfully validated will be created immediately.').' '.
                    579:                              &mt('Unvalidated requests will be listed for manual approval/rejection.').'</p>';
1.63    ! raeburn   580:         } elsif (($context ne 'helpdesk') && ($context ne 'displaypending') && ($context ne 'othdomqueue')) {
1.23      raeburn   581:             $output .= '<br /><input type="submit" name="processqueue" value="'.&mt('Save').'" />';
                    582:         }
                    583:         $output .= '</form>';
                    584:     } else {
                    585:         $output .= '<div class="LC_info">';
                    586:         if ($context eq 'course') {
                    587:             $output .= &mt('There are currently no enrollment requests awaiting approval.');
1.56      raeburn   588:         } elsif (($context eq 'pending') || ($context eq 'displaypending')) {
1.23      raeburn   589:             $output .= &mt('There are currently no requests for official courses awaiting validation.');
1.43      raeburn   590:         } elsif ($context eq 'requestauthor') {
                    591:             $output .= &mt('There are currently no requests for Authoring Space awaiting approval.');
                    592:         } elsif ($context eq 'requestusername') {
                    593:             $output .= &mt('There are currently no requests for LON-CAPA accounts awaiting approval.');
1.63    ! raeburn   594:         } elsif ($context eq 'othdomqueue') {
        !           595:             if ($secondary eq 'domain') {
        !           596:                 $output .= &mt('There are currently no domain role assignment(s) for user(s) from another domain queued pending approval');
        !           597:             } elsif ($secondary eq 'author') {
        !           598:                 $output .= &mt('There are currently no co-author role assignment(s) for user(s) from another domain queued pending approval');
        !           599:             } elsif ($secondary eq 'course') {
        !           600:                 $output .= &mt('There are currently no course role assignment(s) for user(s) from another domain queued pending approval');
        !           601:             } elsif ($secondary eq 'community') {
        !           602:                 $output .= &mt('There are currently no community role assignment(s) for user(s) from another domain queued pending approval');
        !           603:             }
        !           604:         } elsif ($context eq 'othdomaction') {
        !           605:             if ($secondary eq 'user') {
        !           606:                 $output .= &mt('There are currently no pending role assignments for you in other domains, queued pending your acceptance of the role.');
        !           607:             } elsif ($secondary eq 'domain') {
        !           608:                 $output .= &mt('There are currently no pending role assignments in other domains, queued pending domain coordinator approval in this domain.');
        !           609:             }
1.23      raeburn   610:         } else {
                    611:             $output .= &mt('There are currently no course or community requests awaiting approval.');
                    612:         }
                    613:         $output .= '</div>';
                    614:     }
                    615:     return $output;
                    616: }
1.1       raeburn   617: 
1.23      raeburn   618: sub build_queue_display {
1.63    ! raeburn   619:     my ($dom,$context,$queue,$secondary) = @_;
1.23      raeburn   620:     return unless (ref($queue) eq 'HASH');
1.63    ! raeburn   621:     my (%crstypes,%roles_by_context);
        !           622:     my $output = &Apache::loncommon::start_data_table().
        !           623:                  &Apache::loncommon::start_data_table_header_row();
        !           624:     unless (($context eq 'pending') || ($context eq 'displaypending') || 
        !           625:             ($context eq 'helpdesk') || ($context eq 'othdomqueue')) {
1.23      raeburn   626:         $output .= '<th>'.&mt('Action').'</th>';
                    627:     }
1.63    ! raeburn   628:     unless (($context eq 'othdomqueue') || (($context eq 'othdomaction') && ($secondary eq 'user'))) {
        !           629:         $output .= '<th>'.&mt('Requestor').'</th>';
        !           630:     }
1.23      raeburn   631:     if ($context eq 'course') {
                    632:         $output .= '<th>'.&mt('Section').'</th>'.
                    633:                    '<th>'.&mt('Date requested').'</th>';
1.30      raeburn   634:     } elsif ($context eq 'requestauthor') {
                    635:         $output .= '<th>'.&mt('Date requested').'</th>';
1.43      raeburn   636:     } elsif ($context eq 'requestusername') {
                    637:         $output .= '<th>'.&mt('Date requested').'</th>'.
                    638:                    '<th>'.&mt('Details').'</th>';
1.63    ! raeburn   639:     } elsif ($context eq 'othdomqueue') {
        !           640:         $output .= '<th>'.&mt('Date requested').'</th>'.
        !           641:                    '<th>'.&mt('Role').'</th>';
        !           642:         if ($secondary eq 'course') {
        !           643:             $output .= '<th>'.&mt('Section').'</th>';
        !           644:         }
        !           645:         $output .= '<th>'.&mt('Requested for').'</th>'.
        !           646:                    '<th>'.&mt('Approval needed from').'</th>';
        !           647:     } elsif ($context eq 'othdomaction') {
        !           648:         $output .= '<th>'.&mt('Date requested').'</th>'.
        !           649:                    '<th>'.&mt('Role type').'</th>'.
        !           650:                    '<th>'.&mt('Location').'</th>';
        !           651:         if ($secondary eq 'domain') {
        !           652:             $output .= '<th>'.&mt('Affected User').'</th>';
        !           653:         }
        !           654:         foreach my $type ('domain','course') {
        !           655:             my @possroles = &Apache::lonuserutils::roles_by_context($type);
        !           656:             $roles_by_context{$type} = \@possroles;
        !           657:         }
1.56      raeburn   658:     } elsif ($context eq 'pending' || $context eq 'displaypending' || $context eq 'stillpending') {
1.23      raeburn   659:         $output .= '<th>'.&mt('Institutional code').'</th>'.
                    660:                    '<th>'.&mt('Date requested').'</th>'.
                    661:                    '<th>'.&mt('Details').'</th>';
                    662:     } else {
                    663:         %crstypes = &Apache::lonlocal::texthash (
                    664:                         official   => 'Official course',
                    665:                         unofficial => 'Unofficial course',
                    666:                         community  => 'Community',
1.38      raeburn   667:                         textbook   => 'Textbook course',
1.53      raeburn   668:                         placement  => 'Placement test',
1.23      raeburn   669:                     );
                    670:         $output .= '<th>'.&mt('Type').'</th>'.
                    671:                    '<th>'.&mt('Date requested').'</th>'.
                    672:                    '<th>'.&mt('Details').'</th>';
                    673:     }
                    674:     $output .= &Apache::loncommon::end_data_table_header_row();
                    675:     my @sortedtimes = sort {$a <=> $b} (keys(%{$queue}));
                    676:     my $count = 0;
                    677:     foreach my $item (@sortedtimes) {
                    678:         if (ref($queue->{$item}) eq 'ARRAY') {
                    679:             foreach my $request (sort(@{$queue->{$item}})) {
                    680:                 my ($row,$approve,$reject,$showtime,$showsec,$namelink,
1.63    ! raeburn   681:                     $detailslink,$crstype,$instcode,$showrole,$adjudicator,
        !           682:                     $location,$showrequester);
1.23      raeburn   683:                 $showtime = &Apache::lonlocal::locallocaltime($item);
                    684:                 if ($context eq 'course') {
                    685:                     my ($puname,$pudom,$pusec) = split(/:/,$request);
                    686:                     $approve = $count.':'.$puname.':'.$pudom.':'.$pusec;
                    687:                     $reject = $puname.':'.$pudom;
                    688:                     $showsec = $pusec;
                    689:                     if ($showsec eq '') {
                    690:                         $showsec = &mt('none');
                    691:                     }
                    692:                     $namelink = &Apache::loncommon::aboutmewrapper(
                    693:                                 &Apache::loncommon::plainname($puname,$pudom),
                    694:                                 $puname,$pudom);
1.30      raeburn   695:                 } elsif ($context eq 'requestauthor') {
                    696:                     if (&Apache::lonnet::homeserver($request,$dom) ne 'no_host') {
                    697:                         $approve = $count.':'.$request;
1.63    ! raeburn   698:                         $reject = $request;
1.30      raeburn   699:                         $namelink = &Apache::loncommon::aboutmewrapper(
                    700:                                     &Apache::loncommon::plainname($request,$dom),
                    701:                                     $request,$dom);
                    702:                     }
1.43      raeburn   703:                 } elsif ($context eq 'requestusername') {
                    704:                     if (&Apache::lonnet::homeserver($request,$dom) eq 'no_host') {
                    705:                         my $queued = 'approval';
                    706:                         $approve = $count.':'.$request;
                    707:                         $reject = $request;
                    708:                         $detailslink='<a href="javascript:openusernamereqdisplay('.
                    709:                                      "'$dom','$request','$queued'".');">'.$request.'</a>';
                    710:                         $namelink = $request;
                    711:                     }
1.63    ! raeburn   712:                 } elsif ($context eq 'othdomqueue') {
        !           713:                     my ($uname,$udom,$role,$adj,$requester,$sec) = split(/:/,$request);
        !           714:                     if ($adj eq 'user') {
        !           715:                         $adjudicator = &mt('Role Assignee');
        !           716:                     } elsif ($adj eq 'domain') {
        !           717:                         $adjudicator = &mt("[_1] in user's domain",
        !           718:                                            &Apache::lonnet::plaintext('dc'));
        !           719:                     }
        !           720:                     my $crstype;
        !           721:                     $showrole = &Apache::lonnet::plaintext($role,$crstype);
        !           722:                     unless (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') {
        !           723:                         $namelink = &Apache::loncommon::plainname($uname,$udom)." ($uname:$udom)";
        !           724:                     }
        !           725:                     if ($secondary eq 'course') {
        !           726:                         $showsec = $sec;
        !           727:                         if ($showsec eq '') {
        !           728:                             $showsec = &mt('none');
        !           729:                         }
        !           730:                     }
        !           731:                 } elsif ($context eq 'othdomaction') {
        !           732:                     my ($extent,$role,$crstype);
        !           733:                     my ($info,$requester) = map { &unescape($_); } split(/:/,$request);
        !           734:                     if ($secondary eq 'user') {
        !           735:                         ($extent,$role) = split(/:/,$info);
        !           736:                         $approve = $count.':'.$extent.':'.$role;
        !           737:                         $reject = $extent.':'.$role;
        !           738:                     } elsif ($secondary eq 'domain') {
        !           739:                         (my $uname,$extent,$role) = split(/:/,$info);
        !           740:                         $approve = $count.':'.$extent.':'.$role.':'.$uname.':'.$dom;
        !           741:                         $reject = $extent.':'.$role.':'.$uname.':'.$dom;
        !           742:                         unless (&Apache::lonnet::homeserver($uname,$dom) eq 'no_host') {
        !           743:                             $namelink = &Apache::loncommon::plainname($uname,$dom);
        !           744:                             unless ($namelink eq $uname.':'.$dom) {
        !           745:                                 $namelink .= ' ('.$uname.':'.$dom.')';
        !           746:                             }
        !           747:                         }
        !           748:                     }
        !           749:                     if (($role eq 'ca') || ($role eq 'aa')) {
        !           750:                         my ($audom,$auname) = ($extent =~ m{^/($match_domain)/($match_username)$});
        !           751:                         $location = &mt('Author').': '.&Apache::loncommon::plainname($auname,$audom);
        !           752:                     } elsif ($role eq 'co') {
        !           753:                         my ($cdom,$cnum)  = ($extent =~ m{^/($match_domain)/($match_courseid)});
        !           754:                         if (&Apache::lonnet::is_course($cdom,$cnum)) {
        !           755:                             my %info = &Apache::lonnet::coursedescription("$cdom/$cnum",{'one_time' => 1});
        !           756:                             $crstype = $info{'type'};
        !           757:                             $location = &mt('Community').': '.$info{'description'};
        !           758:                             $showrole = &Apache::lonnet::plaintext($role,'Community');
        !           759:                         }
        !           760:                     } elsif ($role =~ m{^cr/}) {
        !           761:                         $showrole = &Apache::lonnet::plaintext($role,$crstype);
        !           762:                         my ($cdom,$cnum,$csec)  = ($extent =~ m{^/($match_domain)/($match_courseid)(?:|/(\w+))$});
        !           763:                         if (&Apache::lonnet::is_course($cdom,$cnum)) {
        !           764:                             my %info = &Apache::lonnet::coursedescription("$cdom/$cnum",{'one_time' => 1});
        !           765:                             $crstype = $info{'type'};
        !           766:                             $location = &mt($crstype).': '.$info{'description'};
        !           767:                             if ($csec ne '') {
        !           768:                                 $location .= ' '.&mt('Section').': '.$csec;
        !           769:                             }
        !           770:                         }
        !           771:                     } else {
        !           772:                         foreach my $type ('course','domain') {
        !           773:                             if (grep(/^\Q$role\E$/,@{$roles_by_context{$type}})) {
        !           774:                                 if ($type eq 'course') {
        !           775:                                     my ($cdom,$cnum,$csec) = ($extent =~ m{^/($match_domain)/($match_courseid)(?:|/(\w+))$});
        !           776:                                     if (&Apache::lonnet::is_course($cdom,$cnum)) {
        !           777:                                         my %info = &Apache::lonnet::coursedescription("$cdom/$cnum",{'one_time' => 1});
        !           778:                                         $crstype = $info{'type'};
        !           779:                                         $location = &mt($crstype).': '.$info{'description'};
        !           780:                                         if ($csec ne '') {
        !           781:                                             $location .= ' '.&mt('Section').': '.$csec;
        !           782:                                         }
        !           783:                                     }
        !           784:                                 } else {
        !           785:                                     my ($domain)  = ($extent =~ m{^/($match_domain)/});
        !           786:                                     $location = &mt('Domain').': '.&Apache::lonnet::domain($domain,'description');
        !           787:                                 }
        !           788:                                 last;
        !           789:                             }
        !           790:                         }
        !           791:                     }
        !           792:                     if ($role =~ m{^cr/($match_domain)/($match_username)/(\w+)$}) {
        !           793:                         my ($crudom,$cruname,$rolename) = ($1,$2,$3);
        !           794:                         my $creator = &Apache::loncommon::plainname($cruname,$crudom);
        !           795:                         unless ($creator eq $cruname.':'.$crudom) {
        !           796:                             $creator .= ' ('.$cruname.':'.$crudom.')';
        !           797:                         }
        !           798:                         $showrole = &mt('Custom role').': '.$rolename.'<br />'.
        !           799:                                     &mt('Created by').' '.$creator;
        !           800:                     } else {
        !           801:                         $showrole = &Apache::lonnet::plaintext($role,$crstype);
        !           802:                     }
        !           803:                     my ($requname,$requdom) = split(/:/,$requester);
        !           804:                     $showrequester = &Apache::loncommon::plainname($requname,$requdom);
        !           805:                     unless ($showrequester eq $requname.':'.$requdom) {
        !           806:                         $showrequester .= ' ('.$requname.':'.$requdom.')';
        !           807:                     }
1.23      raeburn   808:                 } else {
                    809:                     my ($cnum,$ownername,$ownerdom,$type,$cdesc);
1.43      raeburn   810:                     my $queued = 'approval'; 
1.56      raeburn   811:                     if ($context eq 'pending' || $context eq 'displaypending' || $context eq 'stillpending') {
1.23      raeburn   812:                         ($cnum,$ownername,$ownerdom,$instcode,$cdesc)=split(/:/,$request,5);
1.43      raeburn   813:                         $queued = 'pending';                        
1.1       raeburn   814:                     } else {
1.23      raeburn   815:                         ($cnum,$ownername,$ownerdom,$type,$cdesc)=split(/:/,$request,5);
1.1       raeburn   816:                         $crstype = $type;
                    817:                         if (defined($crstypes{$type})) {
                    818:                             $crstype = $crstypes{$type};
                    819:                         }
                    820:                     }
1.23      raeburn   821:                     $detailslink='<a href="javascript:opencoursereqdisplay('.
1.43      raeburn   822:                                   "'$dom','$cnum','$queued'".');">'.$cdesc.'</a>';
1.23      raeburn   823:                     $approve = $count.':'.$cnum;
                    824:                     $reject = $cnum;
                    825:                     $namelink = &Apache::loncommon::aboutmewrapper(
                    826:                                 &Apache::loncommon::plainname($ownername,$ownerdom),
                    827:                                 $ownername,$ownerdom);
                    828:                 }
1.63    ! raeburn   829:                 unless (($context eq 'pending') || ($context eq 'displaypending') || 
        !           830:                         ($context eq 'helpdesk') || ($context eq 'othdomqueue')) {
1.1       raeburn   831:                     $row = '<td><span class="LC_nobreak"><label>'.
1.30      raeburn   832:                            '<input type="radio" value="'.$approve.'" name="'.$count.'radioreq" />'.&mt('Approve').'</label>'.
                    833:                            '<label>'.('&nbsp;'x2).
                    834:                            '<input type="radio" value="'.$reject.'" name="'.$count.'radioreq" />'.&mt('Reject').'</label>'.
                    835:                            '<label>'.('&nbsp;'x2).
1.29      golterma  836:                            '<input type="radio" value="'."later:".$reject.'" name="'.$count.'radioreq" checked />'.&mt('Decide Later').
                    837:                            '</label></span><br /></td>';
1.1       raeburn   838:                 }
1.63    ! raeburn   839:                 unless (($context eq 'othdomqueue') || ($context eq 'othdomaction')) {
        !           840:                     $row .= '<td>'.$namelink.'</td>'."\n";
        !           841:                 }
1.23      raeburn   842:                 if ($context eq 'course') {
                    843:                     $row .= '<td>'.$showsec.'</td>'."\n".
                    844:                             '<td>'.$showtime.'</td>'."\n";
1.30      raeburn   845:                 } elsif ($context eq 'requestauthor') {
                    846:                     $row .= '<td>'.$showtime.'</td>'."\n";
1.43      raeburn   847:                 } elsif ($context eq 'requestusername') {
                    848:                     $row .= '<td>'.$showtime.'</td>'."\n".
                    849:                             '<td>'.$detailslink.'</td>'."\n";
1.63    ! raeburn   850:                 } elsif ($context eq 'othdomqueue') {
        !           851:                     $row .= '<td>'.$showtime.'</td>'."\n".
        !           852:                             '<td>'.$showrole.'</td>'."\n";
        !           853:                     if ($secondary eq 'course') {
        !           854:                         $row .= '<td>'.$showsec.'</td>'."\n";
        !           855:                     }
        !           856:                     $row .= '<td>'.$namelink.'</td>'."\n".
        !           857:                             '<td>'.$adjudicator.'</td>'."\n";
        !           858:                 } elsif ($context eq 'othdomaction') {
        !           859:                     if ($secondary eq 'domain') {
        !           860:                         $row .= '<td>'.$showrequester.'</td>'."\n";
        !           861:                     }
        !           862:                     $row .= '<td>'.$showtime.'</td>'."\n".
        !           863:                             '<td>'.$showrole.'</td>'."\n".
        !           864:                             '<td>'.$location.'</td>'."\n";
        !           865:                     if ($secondary eq 'domain') {
        !           866:                         $row .= '<td>'.$namelink.'</td>'."\n";
        !           867:                     }
        !           868:                 } else {
1.56      raeburn   869:                     if ($context eq 'pending' || $context eq 'displaypending' || $context eq 'stillpending') {
1.23      raeburn   870:                         $row .= '<td>'.$instcode.'</td>'."\n";
                    871:                     } else {
                    872:                         $row .= '<td>'.$crstype.'</td>'."\n";
                    873:                     }
                    874:                     $row .= '<td>'.$showtime.'</td>'."\n".
                    875:                             '<td>'.$detailslink.'</td>'."\n";
                    876:                 }
                    877:                 $output .= &Apache::loncommon::start_data_table_row()."\n".
                    878:                            $row.
                    879:                            &Apache::loncommon::end_data_table_row()."\n";
                    880:                 $count ++;
1.1       raeburn   881:             }
                    882:         }
                    883:     }
1.23      raeburn   884:     $output .= &Apache::loncommon::end_data_table();
1.1       raeburn   885:     return $output;
                    886: }
                    887: 
                    888: sub update_request_queue {
                    889:     my ($context,$cdom,$cnum,$coursedesc) = @_;
                    890:     my ($output,$access_start,$access_end,$limit,$cap,$notifylist,$namespace,
1.26      raeburn   891:         $stucounts,$idx,$classlist,%requesthash,$cid,$domdesc,$now,
                    892:         $sender,$approvedmsg,$rejectedmsg,$beneficiary,
1.2       raeburn   893:         @existing,@missingreq,@invalidusers,@limitexceeded,@completed,
1.19      raeburn   894:         @processing_errors,@warn_approves,@warn_rejects,@approvals,@warn_dels,
1.30      raeburn   895:         @rejections,@rejectionerrors,@nopermissions,%courseroles,@toremove,
                    896:         %communityroles,%domdefs,%approvalmsg,%rejectionmsg,$crstype,$queue,
1.63    ! raeburn   897:         $firsturl,$uniquecode,%codes,%roles_by_context,%requesteractive,
        !           898:         %gotroles);
1.29      golterma  899:     my $count=0;
1.43      raeburn   900:     while (my $item = $env{'form.'.$count.'radioreq'}) {
                    901:         if ($item =~ /^\d+:/) {
                    902:             push(@approvals,$item);
                    903:         } elsif ($item !~ /^later:/) {
                    904:             push(@rejections,$item);
1.29      golterma  905:         }
1.43      raeburn   906:         $count ++;
1.29      golterma  907:     }
1.1       raeburn   908:     $now = time;
                    909:     $sender = $env{'user.name'}.':'.$env{'user.domain'};
                    910:     if ($context eq 'course') {
                    911:         $namespace = 'selfenrollrequests';
                    912:         $beneficiary = 'enroller';
                    913:         $cid = $env{'request.course.id'};
1.12      raeburn   914:         $crstype = lc(&Apache::loncommon::course_type());
1.54      raeburn   915:         $firsturl = &Apache::lonnet::course_portal_url($cnum,$cdom);
1.1       raeburn   916:         %requesthash = &Apache::lonnet::dump($namespace,$cdom,$cnum);
                    917:         $access_start =  $env{'course.'.$cid.'.internal.selfenroll_start_access'};
                    918:         $access_end =  $env{'course.'.$cid.'.internal.selfenroll_end_access'};
                    919:         $limit = $env{'course.'.$cid.'.internal.selfenroll_limit'};
                    920:         $cap = $env{'course.'.$cid.'.internal.selfenroll_cap'};
                    921:         $notifylist = $env{'course.'.$cid.'.internal.selfenroll_notifylist'};
                    922:         ($stucounts,$idx,$classlist) = &get_student_counts($cdom,$cnum);
                    923:         $approvedmsg = [{
                    924:                             mt => 'Your request for enrollment has been approved.',
                    925:                         },
                    926:                         {
1.28      raeburn   927:                             mt   => 'Visit [_1] to log-in and access the course',
1.25      raeburn   928:                             args => [$firsturl],
1.1       raeburn   929:                         }];
                    930:         $rejectedmsg =  [{
                    931:                             mt => 'Your request for enrollment has not been approved.',
                    932:                         }];
1.30      raeburn   933:     } elsif ($context eq 'requestauthor') {
                    934:         $namespace = 'requestauthorqueue';
                    935:         $beneficiary = 'requestauthor';
                    936:         %requesthash = &Apache::lonnet::dump_dom($namespace,$cdom);
                    937:         my %domdefs = &Apache::lonnet::get_domain_defaults($cdom);
                    938:         if (ref($domdefs{'requestauthor'}) eq 'HASH') {
                    939:             if (ref($domdefs{'requestauthor'}{'notify'}) eq 'HASH') {
                    940:                 $notifylist = $domdefs{'requestauthor'}{'notify'}{'approval'};
                    941:             }
                    942:         }
                    943:         my $domconfiguser = &Apache::lonnet::get_domainconfiguser($cdom);
1.54      raeburn   944:         $firsturl = &Apache::lonnet::course_portal_url($domconfiguser,$cdom);
1.30      raeburn   945:         $approvedmsg = [{
1.42      bisitz    946:                             mt => 'Your request for Authoring Space has been approved.',
1.30      raeburn   947:                         },
                    948:                         {
                    949:                             mt   => 'Visit [_1] to log-in and select your author role',
                    950:                             args => [$firsturl],
                    951:                         }];
                    952:         $rejectedmsg =  [{
1.42      bisitz    953:                             mt => 'Your request for Authoring Space has not been approved.',
1.30      raeburn   954:                         }];
                    955:         $domdesc = &Apache::lonnet::domain($cdom);
1.43      raeburn   956:     } elsif ($context eq 'requestusername') {
                    957:         $namespace = 'usernamequeue';
                    958:         $beneficiary = 'requestusername';
                    959:         %requesthash = &Apache::lonnet::dump_dom($namespace,$cdom);
                    960:         my %domconfig = &Apache::lonnet::get_dom('configuration',['usercreation'],$cdom);
                    961:         if (ref($domconfig{'usercreation'}) eq 'HASH') {
                    962:             if (ref($domconfig{'usercreation'}{'cancreate'}) eq 'HASH') {
                    963:                 if (ref($domconfig{'usercreation'}{'cancreate'}{'notify'}) eq 'HASH') {
                    964:                     $notifylist = $domconfig{'usercreation'}{'cancreate'}{'notify'}{'approval'};
                    965:                 }
                    966:             }
                    967:         }
                    968:         my $domconfiguser = &Apache::lonnet::get_domainconfiguser($cdom);
1.54      raeburn   969:         $firsturl = &Apache::lonnet::course_portal_url($domconfiguser,$cdom);
1.43      raeburn   970:         $approvedmsg = [{
                    971:                             mt => 'Your request for a LON-CAPA account has been approved.',
                    972:                         },
                    973:                         {
                    974:                             mt   => 'Visit [_1] to log-in.',
                    975:                             args => [$firsturl],
                    976:                         }];
                    977:         $rejectedmsg =  [{
                    978:                             mt => 'Your request for a LON-CAPA account has not been approved.',
                    979:                         }];
                    980:         $domdesc = &Apache::lonnet::domain($cdom);
1.63    ! raeburn   981:     } elsif (($context eq 'othdombydc') || ($context eq 'othdombyuser')) {
        !           982:         $namespace = 'queuedrolereqs';
        !           983:         $beneficiary = 'requester';
        !           984:         foreach my $type ('domain','course') {
        !           985:             my @possroles = &Apache::lonuserutils::roles_by_context($type);
        !           986:             $roles_by_context{$type} = \@possroles;
        !           987:         }
        !           988:         if ($context eq 'othdombydc') {
        !           989:             my $confname = &Apache::lonnet::get_domainconfiguser($cdom);
        !           990:             %requesthash = &Apache::lonnet::dump($namespace,$cdom,$confname);
        !           991:             $approvedmsg = [{
        !           992:                                 mt => 'The role assignment you requested for a user from another domain has been approved and the role assigned.',
        !           993:                             }];
        !           994:             $rejectedmsg = [{
        !           995:                                 mt => 'The role assignment you requested for a user from another domain has not been approved.',
        !           996:                            }];
        !           997:         } else {
        !           998:             %requesthash = &Apache::lonnet::dump($namespace,$cdom,$cnum);
        !           999:             $approvedmsg = [{
        !          1000:                                 mt => 'The role assignment you requested for a user from another domain has been has been agreed to by the user.',
        !          1001:                             }];
        !          1002:             $rejectedmsg = [{
        !          1003:                                 mt => 'The role assignment you requested for a user from another domain has not been agreed to by the user.',
        !          1004:                            }];
        !          1005:         }
        !          1006:         $domdesc = &Apache::lonnet::domain($cdom);
1.1       raeburn  1007:     } else {
1.2       raeburn  1008:         $domdesc = &Apache::lonnet::domain($cdom);
                   1009:         $namespace = 'courserequestqueue';
                   1010:         $beneficiary = 'courserequestor';
1.23      raeburn  1011:         $queue = 'approval';
                   1012:         if ($env{'form.queue'} eq 'pending') {
                   1013:             $queue = 'pending';
                   1014:         }
                   1015:         %requesthash = &Apache::lonnet::dump_dom($namespace,$cdom,'_'.$queue);
1.2       raeburn  1016:         my %domconfig = &Apache::lonnet::get_dom('configuration',['requestcourses'],$cdom);
                   1017:         if (ref($domconfig{'requestcourses'}) eq 'HASH') {
                   1018:             if (ref($domconfig{'requestcourses'}{'notify'}) eq 'HASH') { 
                   1019:                 $notifylist = $domconfig{'requestcourses'}{'notify'}{'approval'};
                   1020:             }
                   1021:         }
1.12      raeburn  1022:         $approvalmsg{'course'} = 
                   1023:                         [{
1.2       raeburn  1024:                             mt => 'Your course request has been approved.',
                   1025:                         },
                   1026:                         {
1.28      raeburn  1027:                             mt   => 'Visit [_1] to log-in and access the course',
                   1028:                             args => [],
1.2       raeburn  1029:                         }];
1.12      raeburn  1030:         $rejectionmsg{'course'} =
                   1031:                         [{
1.2       raeburn  1032:                             mt => 'Your course request has not been approved.',
                   1033:                         }];
1.12      raeburn  1034: 
                   1035:         $approvalmsg{'community'} = 
                   1036:                         [{
                   1037:                             mt => 'Your community request has been approved.',
                   1038:                         },
                   1039:                         {
1.28      raeburn  1040:                             mt   => 'Visit [_1] to log-in and access the community',
                   1041:                             args => [],
1.12      raeburn  1042:                         }];
                   1043: 
                   1044:         $rejectionmsg{'community'} = 
                   1045:                         [{
                   1046:                             mt => 'Your community request has not been approved.',
                   1047:                         }];
                   1048: 
1.2       raeburn  1049:         %domdefs = &Apache::lonnet::get_domain_defaults($cdom);
                   1050:         my @roles = &Apache::lonuserutils::roles_by_context('course');
                   1051:         foreach my $role (@roles) {
                   1052:             $courseroles{$role}=&Apache::lonnet::plaintext($role,'Course');
                   1053:         }
                   1054:         foreach my $role (@roles) {
                   1055:             $communityroles{$role}=&Apache::lonnet::plaintext($role,'Community');
                   1056:         }
1.1       raeburn  1057:     }
                   1058:     foreach my $item (sort {$a <=> $b} @approvals) {
                   1059:         if ($context eq 'course') {
                   1060:             my ($num,$uname,$udom,$usec) = split(/:/,$item);
                   1061:             my $uhome = &Apache::lonnet::homeserver($uname,$udom);
                   1062:             if ($uhome ne 'no_host') {
                   1063:                 if (exists($requesthash{$uname.':'.$udom})) {
                   1064:                     if (exists($classlist->{$uname.':'.$udom})) {
                   1065:                         if (ref($classlist->{$uname.':'.$udom}) eq 'ARRAY') {
                   1066:                             if (($classlist->{$uname.':'.$udom}->[$idx->{'status'}] eq 'Active') ||
                   1067:                                 ($classlist->{$uname.':'.$udom}->[$idx->{'status'}] eq 'Future')) {
                   1068:                                 push(@existing,$uname.':'.$udom);
                   1069:                                 next;
                   1070:                             }
                   1071:                         }
                   1072:                     }
                   1073:                 } else {
                   1074:                     push(@missingreq,$uname.':'.$udom);
                   1075:                     next;
                   1076:                 }
                   1077:                 if (!grep(/^\Q$item\E$/,@rejections)) {
                   1078:                     if ($limit eq 'allstudents') {
                   1079:                         if ($stucounts->{$limit} >= $cap) {
                   1080:                             push(@limitexceeded,$uname.':'.$udom);
                   1081:                             last;
                   1082:                         }
                   1083:                     } elsif ($limit eq 'selfenrolled') {
                   1084:                         if ($stucounts->{$limit} >= $cap) {
                   1085:                             push(@limitexceeded,$uname.':'.$udom);
                   1086:                             last;
                   1087:                         }
                   1088:                     }
                   1089:                     my $result =
                   1090:                         &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$usec,$access_end,$access_start,'selfenroll',undef,$cdom.'_'.$cnum,1);
                   1091:                     if ($result eq 'ok') {
1.2       raeburn  1092:                         push(@completed,$uname.':'.$udom);
1.1       raeburn  1093:                         $stucounts->{'allstudents'} ++;
                   1094:                         $stucounts->{'selfenrolled'} ++;
                   1095:                         &send_selfserve_notification($uname.':'.$udom,$approvedmsg,
1.26      raeburn  1096:                                        $cid,$coursedesc,$now,$beneficiary,$sender,
                   1097:                                        undef,undef,$crstype);
1.2       raeburn  1098:                         my %userrequest = (
                   1099:                             $cdom.'_'.$cnum => {
                   1100:                                 timestamp   => $now,
                   1101:                                 section     => $usec,
                   1102:                                 adjudicator => $env{'user.name'}.':'.$env{'user.domain'},
                   1103:                                 status      => 'approved',
                   1104:                             }
                   1105:                         );
1.1       raeburn  1106:                         my $userresult =
                   1107:                             &Apache::lonnet::put($namespace,\%userrequest,$udom,$uname);
                   1108:                         if ($userresult ne 'ok') {
                   1109:                             push(@warn_approves,$uname.':'.$udom);
                   1110:                         }
                   1111:                     } else {
1.2       raeburn  1112:                         push(@processing_errors,$uname.':'.$udom);
1.1       raeburn  1113:                     }
                   1114:                 }
                   1115:             } else {
                   1116:                 push(@invalidusers,$uname.':'.$udom);
                   1117:             }
1.30      raeburn  1118:         } elsif ($context eq 'requestauthor') {
                   1119:             my ($num,$uname) = split(/:/,$item);
                   1120:             my $uhome = &Apache::lonnet::homeserver($uname,$cdom);
                   1121:             if ($uhome ne 'no_host') {
                   1122:                 my ($user_is_adv,$user_is_author) = &Apache::lonnet::is_advanced_user($cdom,$uname);
                   1123:                 if ($user_is_author) {
                   1124:                     push(@existing,$uname);
                   1125:                 } elsif (&Apache::lonnet::usertools_access($uname,$cdom,'requestauthor',
                   1126:                                                            undef,'requestauthor')) {
                   1127:                     if (&Apache::lonnet::allowed('cau',$cdom)) {
                   1128:                         if (&Apache::lonnet::assignrole($cdom,$uname,'/'.$cdom.'/','au',undef,time,undef,undef,'requestauthor') eq 'ok') {
                   1129:                             push(@completed,$uname);
                   1130:                             &send_selfserve_notification($uname.':'.$cdom,
                   1131:                                                          $approvedmsg,undef,undef,$now,
                   1132:                                                          $beneficiary,$sender);
                   1133:                             my %userrequest = (
                   1134:                                 author => {
                   1135:                                           timestamp   => $now,
                   1136:                                           adjudicator => $env{'user.name'}.':'.$env{'user.domain'},
                   1137:                                           status      => 'approved',
                   1138:                                         },
                   1139:                                 author_status => 'approved',
                   1140:                             );
                   1141:                             my $userresult =
                   1142:                                 &Apache::lonnet::put('requestauthor',\%userrequest,$cdom,$uname);
                   1143:                             if ($userresult ne 'ok') {
1.43      raeburn  1144:                                 push(@warn_approves,$uname.':'.$cdom);
1.30      raeburn  1145:                             }
                   1146:                         } else {
                   1147:                             push(@processing_errors,$uname);
                   1148:                         }
                   1149:                     } else {
                   1150:                         push(@nopermissions,$uname);
                   1151:                     }
                   1152:                 } else {
                   1153:                     push(@nopermissions,$uname);
                   1154:                 }
                   1155:             } else {
                   1156:                 push(@invalidusers,$uname.':'.$cdom);
                   1157:             }
                   1158:             push(@toremove,(@invalidusers,@nopermissions));
1.43      raeburn  1159:         } elsif ($context eq 'requestusername') {
                   1160:             my ($num,$uname) = split(/:/,$item);
                   1161:             my $dbname = 'nohist_requestedusernames';
                   1162:             my $domconfiguser = &Apache::lonnet::get_domainconfiguser($cdom);
                   1163:             my %curr = &Apache::lonnet::get($dbname,[$uname],$cdom,$domconfiguser);
1.58      raeburn  1164: 
1.43      raeburn  1165:             if (ref($curr{$uname}) eq 'HASH') {
1.58      raeburn  1166:                 my ($logtoken,$serverid,$encpass,$courseid,$id,$firstname,
                   1167:                     $middlename,$lastname,$generation,$inststatus,$email);
1.43      raeburn  1168:                 $curr{$uname}{'timestamp'} = $now;
                   1169:                 $curr{$uname}{'adjudicator'} = $env{'user.name'}.':'.$env{'user.domain'};
                   1170:                 $courseid   = $curr{$uname}{'courseid'};
                   1171:                 $id         = $curr{$uname}{'id'};
                   1172:                 $firstname  = $curr{$uname}{'firstname'};
                   1173:                 $middlename = $curr{$uname}{'middlename'};
                   1174:                 $lastname   = $curr{$uname}{'lastname'};
                   1175:                 $generation = $curr{$uname}{'generation'};
1.46      raeburn  1176:                 $inststatus = $curr{$uname}{'inststatus'};
1.43      raeburn  1177: 
1.58      raeburn  1178:                 if ($curr{$uname}{'email'} ne '') {
                   1179:                     $email = $curr{$uname}{'email'};
                   1180:                 } elsif ($uname =~ /^[^\@]+\@[^\@]+$/) {
                   1181:                     $email = $uname;
                   1182:                 }
                   1183: 
                   1184:                 my $upass;
                   1185:                 if ($curr{$uname}{'tmpinfo'}) {
                   1186:                     my ($key,$caller)=split(/&/,$curr{$uname}{'tmpinfo'});
                   1187:                     if ($caller eq 'createaccount') {
                   1188:                         if ($curr{$uname}{'upass'} eq '') {
                   1189:                             $upass = $curr{$uname}{'upass'};
                   1190:                         } else {
                   1191:                             $upass = &Apache::loncommon::des_decrypt($key,$curr{$uname}{'upass'});
                   1192:                         }
                   1193:                     } else {
                   1194:                         push(@processing_errors,$uname);
                   1195:                     }
                   1196:                 } else {
                   1197:                     $upass = $curr{$uname}{'upass'};
                   1198:                 }
                   1199:                 if ($upass eq '') {
                   1200:                     push(@processing_errors,$uname);
                   1201:                 } else {
1.43      raeburn  1202:                     undef($curr{$uname}{'upass'});
                   1203:                     my $result =
                   1204:                         &Apache::lonnet::modifyuser($cdom,$uname,$id,'internal',$upass,
                   1205:                                                     $firstname,$middlename,$lastname,
1.58      raeburn  1206:                                                     $generation,undef,undef,$email);
1.43      raeburn  1207:                     if ($result eq 'ok') {
                   1208:                         $curr{$uname}{'status'} = 'created';
                   1209:                         push(@completed,$uname); 
                   1210:                         my $uhome = &Apache::lonnet::homeserver($uname,$cdom);
                   1211:                         if ($uhome eq 'no_host') {
                   1212:                             push(@warn_approves,$uname);
                   1213:                         } else {
1.44      raeburn  1214:                             unless (($inststatus eq 'default') || ($inststatus eq '')) {
                   1215:                                 &Apache::lonnet::put('environment',{inststatus => $inststatus},$cdom,$uname);
                   1216:                             }
1.43      raeburn  1217:                             &send_selfserve_notification($uname.':'.$cdom,
                   1218:                                                          $approvedmsg,undef,undef,$now,
                   1219:                                                          $beneficiary,$sender);
                   1220:                             if (&Apache::lonnet::put($dbname,\%curr,$cdom,$domconfiguser) ne 'ok') {
                   1221:                                 push(@warn_approves,$uname);
                   1222:                             }
                   1223:                         }
                   1224:                     } else {
                   1225:                         push(@processing_errors,$uname);
                   1226:                     }
                   1227:                 }
                   1228:             } else {
                   1229:                 push(@invalidusers,$uname);
                   1230:             }
                   1231:             push(@toremove,@invalidusers);
1.63    ! raeburn  1232:         } elsif (($context eq 'othdombydc') || ($context eq 'othdombyuser')) {
        !          1233:             if ($context eq 'othdombydc') {
        !          1234:                 my ($num,$extent,$role,$uname,$udom) = split(/:/,$item);
        !          1235:                 my ($logmsg,$result);
        !          1236:                 if ($udom eq $cdom) {
        !          1237:                     my $key = $uname.':'.$extent.':'.$role;
        !          1238:                     if (exists($requesthash{$key})) {
        !          1239:                         if (ref($requesthash{$key}) eq 'HASH') {
        !          1240:                             my $requester = $requesthash{$key}->{'requester'};
        !          1241:                             my ($requname,$requdom) = split(/:/,$requester);
        !          1242:                             my $start = $requesthash{$key}->{'start'};
        !          1243:                             my $end = $requesthash{$key}->{'end'};
        !          1244:                             my $credits = $requesthash{$key}->{'credits'};
        !          1245:                             my $reqcontext = $requesthash{$key}->{'context'};
        !          1246:                             if ((&Apache::lonnet::homeserver($uname,$udom) ne 'no_host') &&
        !          1247:                                 (&Apache::lonnet::homeserver($requname,$requdom) ne 'no_host')) {
        !          1248:                                 if (($role eq 'ca') || ($role eq 'aa')) {
        !          1249:                                     my ($audom,$auname) = ($extent =~ m{^/($match_domain)/($match_username)$});
        !          1250:                                     if (&Apache::lonnet::homeserver($auname,$audom) ne 'no_host') {
        !          1251:                                         if ($requester eq $auname.':'.$audom) {
        !          1252:                                             unless ($gotroles{$requester}) {
        !          1253:                                                 &requester_roles($auname,$audom,\%requesteractive);
        !          1254:                                                 $gotroles{$requester} = 1;
        !          1255:                                             }
        !          1256:                                             if (ref($requesteractive{$requester}) eq 'HASH') {
        !          1257:                                                 if ($requesteractive{$requester}{':'.$audom.':au'}) {
        !          1258:                                                     $result = &Apache::lonnet::assignrole($udom,$uname,$extent,$role,
        !          1259:                                                                                           $end,$start,'','',$reqcontext);
        !          1260:                                                 }
        !          1261:                                             }
        !          1262:                                         }
        !          1263:                                     }
        !          1264:                                 } elsif (($role eq 'co') || ($role eq 'cc')) {
        !          1265:                                     my ($crsdom,$crsnum)  = ($extent =~ m{^/($match_domain)/($match_courseid)});
        !          1266:                                     if (&Apache::lonnet::is_course($crsdom,$crsnum)) {
        !          1267:                                         my %info = &Apache::lonnet::coursedescription("$crsdom/$crsnum",{'one_time' => 1});
        !          1268:                                         if ((($role eq 'co') && ($info{'type'} eq 'Community')) ||
        !          1269:                                            (($role eq 'cc') && ($info{'type'} ne 'Community'))) {
        !          1270:                                             if ($info{'internal.courseowner'} eq $requester) {
        !          1271:                                                 unless ($gotroles{$requester}) {
        !          1272:                                                     &requester_roles($requname,$requdom,\%requesteractive);
        !          1273:                                                     $gotroles{$requester} = 1;
        !          1274:                                                 }
        !          1275:                                                 if (ref($requesteractive{$requester}) eq 'HASH') {
        !          1276:                                                     if ($requesteractive{$requester}{"$crsnum:$crsdom:$role"}) {
        !          1277:                                                         $result =
        !          1278:                                                             &Apache::loncommon::commit_standardrole($udom,$uname,$extent,$role,$start,
        !          1279:                                                                                                     $end,$crsdom,$crsnum,'',
        !          1280:                                                                                                     $reqcontext);
        !          1281:                                                     }
        !          1282:                                                 }
        !          1283:                                             }
        !          1284:                                         }
        !          1285:                                     }
        !          1286:                                 } elsif ($role =~ m{^(cr)/($match_domain)/($match_username)/(\w+)$}) {
        !          1287:                                     my ($mrole,$crudom,$cruname,$rolename) = ($1,$2,$3,$4);
        !          1288:                                     my ($crsdom,$crsnum,$csec) =
        !          1289:                                         ($extent =~ m{^/($match_domain)/($match_courseid)(?:|/(\w+))$});
        !          1290:                                     if (&Apache::lonnet::is_course($crsdom,$crsnum)) {
        !          1291:                                         my ($rdummy,$roledef) =
        !          1292:                                             &Apache::lonnet::get('roles',["rolesdef_$rolename"],$crudom,$cruname);
        !          1293:                                         if (($rdummy ne 'con_lost') && ($roledef ne '')) {
        !          1294:                                             unless ($gotroles{$requester}) {
        !          1295:                                                 &requester_roles($requname,$requdom,\%requesteractive);
        !          1296:                                                 $gotroles{$requester} = 1;
        !          1297:                                             }
        !          1298:                                             if (ref($requesteractive{$requester}) eq 'HASH') {
        !          1299:                                                 if (&requester_has_perm($crsdom,$crsnum,$mrole,$requesteractive{$requester})) {
        !          1300:                                                     $result = &Apache::loncommon::commit_customrole($udom,$uname,$extent,$crudom,$cruname,
        !          1301:                                                                                                     $rolename,$start,$end,$reqcontext);
        !          1302:                                                 }
        !          1303:                                             }
        !          1304:                                         }
        !          1305:                                     }
        !          1306:                                 } else {
        !          1307:                                     my $process;
        !          1308:                                     foreach my $type ('course','domain') {
        !          1309:                                         if (grep(/^\Q$role\E$/,@{$roles_by_context{$type}})) {
        !          1310:                                             if ($type eq 'course') {
        !          1311:                                                 my ($crsdom,$crsnum,$csec) = ($extent =~ m{^/($match_domain)/($match_courseid)(?:|/(\w+))$});
        !          1312:                                                 if (&Apache::lonnet::is_course($crsdom,$crsnum)) {
        !          1313:                                                     my $typeok;
        !          1314:                                                     if ($role eq 'cc') {
        !          1315:                                                         my %info = &Apache::lonnet::coursedescription("$crsdom/$crsnum",{'one_time' => 1});
        !          1316:                                                         if ($info{'type'} eq 'Course') {
        !          1317:                                                             $typeok = 1;
        !          1318:                                                         }
        !          1319:                                                     } else {
        !          1320:                                                         $typeok = 1;
        !          1321:                                                     }
        !          1322:                                                     if ($typeok) {
        !          1323:                                                         unless ($gotroles{$requester}) {
        !          1324:                                                             &requester_roles($requname,$requdom,\%requesteractive);
        !          1325:                                                             $gotroles{$requester} = 1;
        !          1326:                                                         }
        !          1327:                                                         if (ref($requesteractive{$requester}) eq 'HASH') {
        !          1328:                                                             if (&requester_has_perm($crsdom,$crsnum,$role,$requesteractive{$requester})) {
        !          1329:                                                                 $result =
        !          1330:                                                                     &Apache::loncommon::commit_standardrole($udom,$uname,$extent,$role,$start,
        !          1331:                                                                                                             $end,$crsdom,$crsnum,$csec,
        !          1332:                                                                                                             $reqcontext,$credits);
        !          1333:                                                             }
        !          1334:                                                         }
        !          1335:                                                     }
        !          1336:                                                 }
        !          1337:                                             } else {
        !          1338:                                                 my ($domain)  = ($extent =~ m{^/($match_domain)/});
        !          1339:                                                 if (&Apache::lonnet::domain($domain) ne '') {
        !          1340:                                                     unless ($gotroles{$requester}) {
        !          1341:                                                         &requester_roles($requname,$requdom,\%requesteractive);
        !          1342:                                                         $gotroles{$requester} = 1;
        !          1343:                                                     }
        !          1344:                                                     if (&requester_has_perm($domain,'',$role,$requesteractive{$requester})) {
        !          1345:                                                         $result = &Apache::lonnet::assignrole($udom,$uname,$extent,$role,
        !          1346:                                                                                               $end,$start,'','',$reqcontext);
        !          1347:                                                     }
        !          1348:                                                 }
        !          1349:                                             }
        !          1350:                                             last;
        !          1351:                                         }
        !          1352:                                     }
        !          1353:                                 }
        !          1354:                             }
        !          1355:                         }
        !          1356:                     }
        !          1357:                 }
        !          1358:                 if ($result eq 'ok') {
        !          1359:                     push(@completed,$item);
        !          1360:                 }
        !          1361:             } else {
        !          1362:                 my ($num,$extent,$role) = split(/:/,$item);
        !          1363:                 if (exists($requesthash{$extent.':'.$role})) {
        !          1364:                     if (ref($requesthash{$extent.':'.$role}) eq 'HASH') {
        !          1365: #FIXME
        !          1366: #check if extent is valid
        !          1367: #check if role is valid
        !          1368: #check requester privs
        !          1369:                     }
        !          1370:                 }
        !          1371:             }
1.1       raeburn  1372:         } else {
1.2       raeburn  1373:             my ($num,$cnum) = split(':',$item);
1.23      raeburn  1374:             if (ref($requesthash{$cnum.'_'.$queue}) eq 'HASH') {
1.2       raeburn  1375:                 if (&Apache::lonnet::homeserver($cnum,$cdom) eq 'no_host') {
1.23      raeburn  1376:                     my $ownername = $requesthash{$cnum.'_'.$queue}{'ownername'};
                   1377:                     my $ownerdom = $requesthash{$cnum.'_'.$queue}{'ownerdom'};
                   1378:                     $crstype = $requesthash{$cnum.'_'.$queue}{'crstype'};
                   1379:                     my $coursedesc = $requesthash{$cnum.'_'.$queue}{'description'};
1.2       raeburn  1380:                     my $longroles = \%courseroles;
                   1381:                     if ($crstype eq 'community') {
                   1382:                         $longroles = \%communityroles;
                   1383:                     }
1.5       raeburn  1384:                     my $cancreate;
                   1385:                     if ($cdom eq $ownerdom) {
                   1386:                         if (&Apache::lonnet::usertools_access($ownername,$ownerdom,$crstype,
                   1387:                                                               undef,'requestcourses')) {
                   1388:                             $cancreate = 1;
                   1389:                         }
                   1390:                     } else {
                   1391:                         my %userenv = &Apache::lonnet::userenvironment($ownerdom,$ownername,'reqcrsotherdom.'.$crstype);
                   1392:                         if ($userenv{'reqcrsotherdom.'.$crstype}) {
                   1393:                             my @doms = split(',',$userenv{'reqcrsotherdom.'.$crstype});
                   1394:                             if (grep(/^\Q$cdom\E:/,@doms)) {
                   1395:                                 $cancreate = 1;
                   1396:                             }
                   1397:                         }
                   1398:                     }
                   1399:                     if ($cancreate) {
1.2       raeburn  1400:                         my $requestkey = $cdom.'_'.$cnum;
                   1401:                         my %history = 
                   1402:                             &Apache::lonnet::restore($requestkey,'courserequests',
                   1403:                                                      $ownerdom,$ownername);
                   1404:                         if ((ref($history{'details'}) eq 'HASH') && 
1.23      raeburn  1405:                             ($history{'disposition'} eq $queue)) {
1.59      raeburn  1406:                             my ($logmsg,$newusermsg,$addresult,$enrollcount,$response,
                   1407:                                 $keysmsg,$code,%customitems);
                   1408:                             my $clonemsg = [];
1.41      raeburn  1409:                             my $fullname = '';
                   1410:                             my $inprocess = &Apache::lonnet::auto_crsreq_update($cdom,$cnum,$crstype,'process',$ownername,
                   1411:                                                                                 $ownerdom,$fullname,$coursedesc);
                   1412:                             if (ref($inprocess) eq 'HASH') {
                   1413:                                 foreach my $key (keys(%{$inprocess})) {
                   1414:                                     if (exists($history{'details'}{$key})) { 
                   1415:                                         $customitems{$key} = $history{'details'}{$key};
                   1416:                                     }
                   1417:                                 }
                   1418:                             }
1.50      raeburn  1419:                             if ($history{'details'}{'clonecrs'}) {
                   1420:                                 $customitems{'_LC_clonefrom'} = $history{'details'}{'clonedom'}.'_'.$history{'details'}{'clonecrs'};
                   1421:                             }
1.59      raeburn  1422:                             my ($result,$postprocess) = &course_creation($cdom,$cnum,$context,$history{'details'},
                   1423:                                                         \$logmsg,$clonemsg,\$newusermsg,\$addresult,\$enrollcount,
1.41      raeburn  1424:                                                         \$response,\$keysmsg,\%domdefs,$longroles,\$code,\%customitems);
1.2       raeburn  1425:                             if ($result eq 'created') {
1.12      raeburn  1426:                                 if ($crstype eq 'community') {
                   1427:                                     $approvedmsg = $approvalmsg{'community'};
                   1428:                                 } else {
                   1429:                                     $approvedmsg = $approvalmsg{'course'};
                   1430:                                 }
1.54      raeburn  1431:                                 my $firsturl = &Apache::lonnet::course_portal_url($cnum,$cdom);
1.28      raeburn  1432:                                 if (ref($approvedmsg) eq 'ARRAY') {
                   1433:                                     if (ref($approvedmsg->[1]) eq 'HASH') {
                   1434:                                         $approvedmsg->[1]->{'args'} = [$firsturl];
                   1435:                                     }
1.59      raeburn  1436:                                     if ((ref($clonemsg) eq 'ARRAY') && (@{$clonemsg})) {
                   1437:                                         push(@{$approvedmsg},@{$clonemsg});
                   1438:                                     }
1.39      raeburn  1439:                                     if ($code) {
                   1440:                                         push(@{$approvedmsg},
                   1441:                                             {
                   1442:                                               mt   => 'Students can automatically select your course by entering this code: [_1]',
                   1443:                                               args => [$code],
                   1444:                                             });
                   1445:                                         $codes{$cnum} = $code;
                   1446:                                     }
1.41      raeburn  1447:                                     if (ref($postprocess) eq 'HASH') {
                   1448:                                         if (ref($postprocess->{'createdmsg'}) eq 'ARRAY') {
                   1449:                                             foreach my $item (@{$postprocess->{'createdmsg'}}) {
                   1450:                                                 if (ref($item) eq 'HASH') {
                   1451:                                                     if ($item->{'mt'} ne '') {
                   1452:                                                         push(@{$approvedmsg},$item);
                   1453:                                                     }
                   1454:                                                 }
                   1455:                                             }
                   1456:                                         }
                   1457:                                     }
1.28      raeburn  1458:                                 }
1.2       raeburn  1459:                                 push(@completed,$cnum);
1.19      raeburn  1460:                                 
1.23      raeburn  1461:                                 unless (&Apache::lonnet::del_dom($namespace,[$cnum.'_'.$queue],$cdom) eq 'ok') {
1.19      raeburn  1462:                                     push(@warn_dels,$cnum);
                   1463:                                 }
1.26      raeburn  1464:                                 &send_selfserve_notification($ownername.':'.$ownerdom,
                   1465:                                               $approvedmsg,$cid,$coursedesc,$now,
                   1466:                                               $beneficiary,$sender,undef,undef,$crstype);
1.2       raeburn  1467:                                 my %reqhash = (
                   1468:                                                 reqtime     => $history{'reqtime'},
                   1469:                                                 crstype     => $history{'crstype'},
                   1470:                                                 details     => $history{'details'},
                   1471:                                                 disposition => $history{'disposition'},
                   1472:                                                 status      => 'created',
                   1473:                                                 adjudicator => $env{'user.name'}.':'.
                   1474:                                                                $env{'user.domain'},
                   1475:                                               );
                   1476:                                 my $userresult =
                   1477:                                     &Apache::lonnet::store_userdata(\%reqhash,$requestkey,
                   1478:                                                    'courserequests',$ownerdom,$ownername);
                   1479:                                 if ($userresult eq 'ok') {
                   1480:                                     my %status = (
                   1481:                                                    'status:'.$cdom.':'.$cnum => 'created'
                   1482:                                                  );
                   1483:                                     my $statusresult = 
                   1484:                                         &Apache::lonnet::put('courserequests',\%status,
                   1485:                                                              $ownerdom,$ownername);
                   1486:                                     if ($statusresult ne 'ok') {
                   1487:                                         push(@warn_approves,$cnum);
                   1488:                                     }
                   1489:                                 }
                   1490:                                 if ($userresult ne 'ok') {
                   1491:                                     push(@warn_approves,$cnum);
                   1492:                                 }
                   1493:                             } else {
                   1494:                                 push(@processing_errors,$cnum);
                   1495:                             }
                   1496:                         } else {
                   1497:                             push(@processing_errors,$cnum);
                   1498:                         }
                   1499:                     } else {
1.5       raeburn  1500:                         push(@nopermissions,$cnum);
1.2       raeburn  1501:                     }
                   1502:                 } else {
                   1503:                     push(@existing,$cnum);
                   1504:                 }
                   1505:             } else {
                   1506:                 push(@missingreq,$cnum);
                   1507:             }
1.1       raeburn  1508:         }
                   1509:     }
1.2       raeburn  1510:     my @changes = (@completed,@rejections);
                   1511:     if ($context eq 'domain') {
1.23      raeburn  1512:         @changes = map {$_.'_'.$queue} (@changes);
1.30      raeburn  1513:     } elsif ($context eq 'requestauthor') {
                   1514:         @changes = map {$_.'_approval'} (@changes);
1.43      raeburn  1515:     } elsif ($context eq 'requestusername') {
                   1516:         @changes = map {&escape($_).'_approval'} (@changes);
1.63    ! raeburn  1517:     } elsif (($context eq 'othdombydc') || ($context eq 'othdombyuser')) {
        !          1518:         @changes = ();
1.2       raeburn  1519:     }
1.1       raeburn  1520:     if (@rejections) {
1.3       raeburn  1521:         foreach my $item (@rejections) {
1.30      raeburn  1522:             if (($context eq 'course') || ($context eq 'requestauthor')) {
1.43      raeburn  1523:                 my ($user,$uname,$udom,%userrequest,$key,$dbname);
1.30      raeburn  1524:                 if ($context eq 'requestauthor') {
                   1525:                     $uname = $item;
                   1526:                     $udom = $cdom;
                   1527:                     $user = $uname.':'.$udom;
                   1528:                     $key = 'author';
1.43      raeburn  1529:                     $dbname = 'requestauthor';
1.30      raeburn  1530:                 } else {
                   1531:                     $user = $item;
                   1532:                     ($uname,$udom) = split(/:/,$user);
                   1533:                     $key = $cdom.'_'.$cnum;
1.43      raeburn  1534:                     $dbname = $namespace;
1.30      raeburn  1535:                 }
1.2       raeburn  1536:                 &send_selfserve_notification($user,$rejectedmsg,$cid,$coursedesc,
1.26      raeburn  1537:                                              $now,$beneficiary,$sender,undef,undef,
                   1538:                                              $crstype);
1.30      raeburn  1539:                 %userrequest = (
                   1540:                     $key => {
1.1       raeburn  1541:                         timestamp   => $now,
                   1542:                         adjudicator => $env{'user.name'}.':'.$env{'user.domain'},
1.30      raeburn  1543:                         status      => 'rejection',
1.1       raeburn  1544:                     }
                   1545:                 );
1.30      raeburn  1546:                 if ($context eq 'requestauthor') {
                   1547:                     $userrequest{'author_status'} = 'rejection';  
                   1548:                 }
1.1       raeburn  1549:                 my $userresult =
1.43      raeburn  1550:                     &Apache::lonnet::put($dbname,\%userrequest,$udom,$uname);
1.1       raeburn  1551:                 if ($userresult ne 'ok') {
1.30      raeburn  1552:                     push(@warn_rejects,$item);
1.1       raeburn  1553:                 }
1.43      raeburn  1554:             } elsif ($context eq 'requestusername') {
                   1555:                 my ($uname,$udom,$dbname);
                   1556:                 $uname = $item;
                   1557:                 $udom = $cdom;
                   1558:                 $dbname = 'nohist_requestedusernames';
                   1559:                 my $domconfiguser = &Apache::lonnet::get_domainconfiguser($cdom);
                   1560:                 my %curr = &Apache::lonnet::get($dbname,[$uname],$cdom,$domconfiguser);
                   1561:                 if (ref($curr{$uname}) eq 'HASH') {
                   1562:                      $curr{$uname}{'status'} = 'rejected';
                   1563:                      $curr{$uname}{'timestamp'} = $now;
                   1564:                      $curr{$uname}{'adjudicator'} =  $env{'user.name'}.':'.$env{'user.domain'};
                   1565:                      undef($curr{$uname}{'tmpinfo'});
                   1566:                      undef($curr{$uname}{'upass'}); 
                   1567:                 }
                   1568:                 my $userresult =
                   1569:                     &Apache::lonnet::put($dbname,\%curr,$cdom,$domconfiguser);
                   1570:                 if ($userresult ne 'ok') {
                   1571:                     push(@warn_rejects,$uname);
                   1572:                 }
1.63    ! raeburn  1573:             } elsif (($context eq 'othdombydc') || ($context eq 'othdombyuser')) {
        !          1574: #FIXME
1.1       raeburn  1575:             } else {
1.3       raeburn  1576:                 my $cnum = $item;
1.23      raeburn  1577:                 if (ref($requesthash{$cnum.'_'.$queue}) eq 'HASH') {
1.3       raeburn  1578:                     if (&Apache::lonnet::homeserver($cnum,$cdom) eq 'no_host') {
                   1579:                         my $requestkey = $cdom.'_'.$cnum;
1.23      raeburn  1580:                         my $ownername = $requesthash{$cnum.'_'.$queue}{'ownername'};
                   1581:                         my $ownerdom = $requesthash{$cnum.'_'.$queue}{'ownerdom'};
                   1582:                         my $coursedesc = $requesthash{$cnum.'_'.$queue}{'description'};
                   1583:                         $crstype = $requesthash{$cnum.'_'.$queue}{'crstype'};
1.12      raeburn  1584:                         if ($crstype eq 'community') {
                   1585:                             $rejectedmsg = $rejectionmsg{'community'};
                   1586:                         } else {
                   1587:                             $rejectedmsg = $rejectionmsg{'course'};
                   1588:                         }
1.2       raeburn  1589:                         &send_selfserve_notification($ownername.':'.$ownerdom,$rejectedmsg,
                   1590:                                                      $cid,$coursedesc,$now,$beneficiary,
1.12      raeburn  1591:                                                      $sender,undef,undef,$crstype);
1.2       raeburn  1592:                         my %history =
1.3       raeburn  1593:                             &Apache::lonnet::restore($requestkey,'courserequests',
1.2       raeburn  1594:                                                      $ownerdom,$ownername);
                   1595:                         if ((ref($history{'details'}) eq 'HASH') &&
1.23      raeburn  1596:                             ($history{'disposition'} eq $queue)) {
1.2       raeburn  1597:                             my %reqhash = (
                   1598:                                             reqtime     => $history{'reqtime'},
                   1599:                                             crstype     => $history{'crstype'},
                   1600:                                             details     => $history{'details'},
                   1601:                                             disposition => $history{'disposition'},
                   1602:                                             status      => 'rejected',
                   1603:                                             adjudicator => $env{'user.name'}.':'.$env{'user.domain'},
                   1604:                                               );
                   1605:                             my $userresult =
1.3       raeburn  1606:                                 &Apache::lonnet::store_userdata(\%reqhash,$requestkey,
                   1607:                                                 'courserequests',$ownerdom,$ownername);
                   1608:                             if ($userresult eq 'ok') {
                   1609:                                 my %status = (
                   1610:                                                'status:'.$cdom.':'.$cnum => 'rejected'
                   1611:                                              );
                   1612:                                 my $statusresult =
                   1613:                                     &Apache::lonnet::put('courserequests',\%status,
                   1614:                                                          $ownerdom,$ownername);
                   1615:                                 if ($statusresult ne 'ok') {
                   1616:                                     push(@warn_rejects,$cnum);
                   1617:                                 }
                   1618:                             } else {
                   1619:                                 push(@warn_rejects,$cnum);
1.2       raeburn  1620:                             }
1.23      raeburn  1621:                             unless (&Apache::lonnet::del_dom($namespace,[$cnum.'_'.$queue],$cdom) eq 'ok') {
1.19      raeburn  1622:                                 push(@warn_dels,$cnum);
                   1623:                             }
1.3       raeburn  1624:                         } else {
                   1625:                             push(@warn_rejects,$cnum);
1.2       raeburn  1626:                         }
1.3       raeburn  1627:                     } else {
                   1628:                         push(@existing,$cnum);
1.2       raeburn  1629:                     }
1.3       raeburn  1630:                 } else {
                   1631:                     push(@rejectionerrors,$cnum);
1.2       raeburn  1632:                 }
1.1       raeburn  1633:             }
                   1634:         }
                   1635:     }
1.30      raeburn  1636:     if (@toremove) {
1.43      raeburn  1637:         my $domconfiguser = &Apache::lonnet::get_domainconfiguser($cdom);
1.30      raeburn  1638:         foreach my $item (@toremove) {
1.43      raeburn  1639:             if ($context eq 'requestauthor') {
                   1640:                 my %userrequest = (
                   1641:                     author => {
                   1642:                                 timestamp   => $now,
                   1643:                                 adjudicator => $env{'user.name'}.':'.$env{'user.domain'},
                   1644:                                 status      => 'deleted',
                   1645:                               },
                   1646:                               author_status => 'deleted',
                   1647:                 );
                   1648:                 &Apache::lonnet::put('requestauthor',\%userrequest,$cdom,$item);
                   1649:             } elsif ($context eq 'requestusername') {
                   1650:                 my $dbname = 'nohist_requestedusernames';
                   1651:                 my %curr = &Apache::lonnet::get($dbname,[$item],$cdom,$domconfiguser);
                   1652:                 if (ref($curr{$item}) eq 'HASH') {
                   1653:                     $curr{$item}{'status'} = 'deleted';
                   1654:                     $curr{$item}{'timestamp'} = $now;
                   1655:                     $curr{$item}{'adjudicator'} = $env{'user.name'}.':'.$env{'user.domain'};
                   1656:                     undef($curr{$item}{'upass'});
                   1657:                     undef($curr{$item}{'tmpinfo'}); 
                   1658:                 }
                   1659:             }
1.30      raeburn  1660:         }
                   1661:         @toremove = map {$_.'_approval'} (@toremove);
                   1662:         my $delresult = &Apache::lonnet::del_dom($namespace,\@toremove,$cdom);
                   1663:     }
1.1       raeburn  1664:     if (@changes) {
                   1665:         my $delresult;
                   1666:         if ($context eq 'course') {
                   1667:             $delresult = &Apache::lonnet::del($namespace,\@changes,$cdom,$cnum);
                   1668:         } else {
                   1669:             $delresult = &Apache::lonnet::del_dom($namespace,\@changes,$cdom);
                   1670:         }
                   1671:         if ($delresult eq 'ok') {
                   1672:             my $namelink =
                   1673:                 &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'}).' ('.$env{'user.name'}.':'.$env{'user.domain'}.')';
                   1674:             my ($chgmsg,$approvedlist,$rejectedlist);
                   1675:             if ($context eq 'course') {
                   1676:                 $chgmsg = "'Action was taken on the following enrollment requests by [_1].',$namelink";
1.2       raeburn  1677:                 if (@completed) {
                   1678:                     $approvedlist = join("\n",@completed);
1.12      raeburn  1679:                     if ($crstype eq 'community') {
                   1680:                         $output .= '<p>'.&mt('The following were enrolled in the community:').'<ul>';
                   1681:                     } else {
                   1682:                         $output .= '<p>'.&mt('The following were enrolled in the course:').'<ul>';
                   1683:                     }
1.2       raeburn  1684:                     foreach my $user (@completed) {
1.1       raeburn  1685:                         my ($uname,$udom) = split(/:/,$user);
                   1686:                         my $userlink =
                   1687:                             &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$udom),$uname,$udom);
                   1688:                         $output .= '<li>'.$userlink.'</li>';
                   1689:                     }
                   1690:                     $output .= '</ul></p>';
                   1691:                 }
                   1692:                 if (@rejections) {
                   1693:                     $rejectedlist = join("\n",@rejections);
                   1694:                     $output .= '<p>'.&mt('The following enrollment requests were rejected:').'<ul>';
                   1695:                     foreach my $user (@rejections) {
                   1696:                         $output .= '<li>'.$user.'</li>';
                   1697:                     }
                   1698:                     $output .= '</ul></p>';
                   1699:                 }
1.2       raeburn  1700:                 if ($notifylist ne '') {
                   1701:                     &send_selfserve_notification($notifylist,$chgmsg,$cid,$coursedesc,
                   1702:                                                  $now,'coursemanagers',$sender,
1.12      raeburn  1703:                                                  $approvedlist,$rejectedlist,$crstype);
1.2       raeburn  1704:                 }
1.30      raeburn  1705:             } elsif ($context eq 'requestauthor') {
1.42      bisitz   1706:                 $chgmsg = "'Action was taken on the following Authoring Space requests by [_1].',$namelink";
1.30      raeburn  1707:                 if (@completed) {
                   1708:                     $approvedlist = join("\n",@completed);
                   1709:                     $output .= '<p>'.&mt('The following requests were approved:').'<ul>';
                   1710:                     foreach my $uname (@completed) {
                   1711:                         my $userlink =
                   1712:                             &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
                   1713:                         $output .= '<li>'.$userlink.'</li>';
                   1714:                         
                   1715:                     }
                   1716:                     $output .= '</ul></p>';
                   1717:                 }
                   1718:                 if (@rejections) {
                   1719:                     $rejectedlist = join("\n",@rejections);
                   1720:                     $output .= '<p>'.&mt('The following requests were rejected:').'<ul>';
                   1721:                     foreach my $uname (@rejections) {
                   1722:                         my $userlink =
                   1723:                             &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
                   1724:                         $output .= '<li>'.$userlink.'</li>';
                   1725:                     }
                   1726:                     $output .= '</ul></p>';
                   1727:                 }
                   1728:                 if ($notifylist ne '') {
                   1729:                     &send_selfserve_notification($notifylist,$chgmsg,undef,$domdesc,
                   1730:                                                  $now,'authormanagers',$sender,
                   1731:                                                  $approvedlist,$rejectedlist);
                   1732:                 }
1.43      raeburn  1733:             } elsif ($context eq 'requestusername') {
                   1734:                 $chgmsg = "'Action was taken on the following LON-CAPA account requests by [_1].',$namelink";
                   1735:                 if (@completed) {
                   1736:                     $approvedlist = join("\n",@completed);
                   1737:                     $output .= '<p>'.&mt('The following requests were approved:').'<ul>';
                   1738:                     foreach my $uname (@completed) {
                   1739:                         $output .= '<li>'.$uname.'</li>';
                   1740: 
                   1741:                     }
                   1742:                     $output .= '</ul></p>';
                   1743:                 }
                   1744:                 if (@rejections) {
                   1745:                     $rejectedlist = join("\n",@rejections);
                   1746:                     $output .= '<p>'.&mt('The following requests were rejected:').'<ul>';
                   1747:                     foreach my $uname (@rejections) {
                   1748:                         $output .= '<li>'.$uname.'</li>';
                   1749:                     }
                   1750:                     $output .= '</ul></p>';
                   1751:                 }
                   1752:                 if ($notifylist ne '') {
                   1753:                     &send_selfserve_notification($notifylist,$chgmsg,undef,$domdesc,
                   1754:                                                  $now,'usernamemanagers',$sender,
                   1755:                                                  $approvedlist,$rejectedlist);
                   1756:                 }
1.63    ! raeburn  1757:             } elsif (($context eq 'othdombydc') || ($context eq 'othdombyuser')) {
        !          1758: #FIXME
1.1       raeburn  1759:             } else {
1.12      raeburn  1760:                 $chgmsg = "'Action was taken on the following course and community requests by [_1].',$namelink";
1.2       raeburn  1761:                 if (@completed) {
                   1762:                     $approvedlist = join("\n",@completed);
1.12      raeburn  1763:                     $output .= '<p>'.&mt('The following courses/communities were created:').'<ul>';
1.2       raeburn  1764:                     foreach my $cnum (@completed) {
                   1765:                         my $showcourse;
1.23      raeburn  1766:                         if (ref($requesthash{$cnum.'_'.$queue})) {
                   1767:                             $showcourse = $requesthash{$cnum.'_'.$queue}{'description'};
1.2       raeburn  1768:                         } else {
                   1769:                             $showcourse = $cnum;
                   1770:                         }
                   1771:                         my $syllabuslink =
                   1772:                             &Apache::loncommon::syllabuswrapper($showcourse,$cnum,$cdom);
1.40      raeburn  1773:                         if ($codes{$cnum}) {
1.49      raeburn  1774:                             $syllabuslink .= ' '.&mt('Unique code: [_1]',$codes{$cnum});
1.39      raeburn  1775:                         }
1.2       raeburn  1776:                         $output .= '<li>'.$syllabuslink.'</li>';
                   1777:                     }
                   1778:                     $output .= '</ul></p>';
                   1779:                 }
                   1780:                 if (@rejections) {
                   1781:                     $rejectedlist = join("\n",@rejections);
                   1782:                     $output .= '<p>'.&mt('The following requests were rejected:').'<ul>';
                   1783:                     foreach my $cnum (@rejections) {
                   1784:                         my $showcourse;
1.23      raeburn  1785:                         if (ref($requesthash{$cnum.'_'.$queue})) {
                   1786:                             $showcourse = $requesthash{$cnum.'_'.$queue}{'description'};
1.2       raeburn  1787:                         } else {
                   1788:                             $showcourse = $cnum;
                   1789:                         }
                   1790:                         $output .= '<li>'.$showcourse.'</li>';
                   1791:                     }
                   1792:                     $output .= '</ul></p>';
                   1793:                 }
                   1794:                 if ($notifylist ne '') {
                   1795:                     &send_selfserve_notification($notifylist,$chgmsg,$cid,$domdesc,
                   1796:                                                  $now,'domainmanagers',$sender,
1.12      raeburn  1797:                                                  $approvedlist,$rejectedlist,$crstype);
1.2       raeburn  1798:                 }
1.1       raeburn  1799:             }
1.43      raeburn  1800:         } else {
                   1801:             if (($context eq 'requestauthor') || ($context eq 'requestusername')) {
                   1802:                 push(@warn_dels,@changes);
                   1803:             }
1.1       raeburn  1804:         }
                   1805:     }
                   1806:     if (@existing) {
                   1807:         if ($context eq 'course') {
                   1808:             $output .= '<p>'.&mt('The following enrollment requests were deleted because the user is already enrolled in the course:').'<ul>';
                   1809:             foreach my $user (@existing) {
                   1810:                 $output .= '<li>'.$user.'</li>';
                   1811:             }
                   1812:             $output .= '</ul></p>';
1.30      raeburn  1813:         } elsif ($context eq 'requestauthor') {
1.42      bisitz   1814:             $output .= '<p>'.&mt('Authoring Space requests from the following users were deleted because one already exists:').'<ul>';
1.30      raeburn  1815:             foreach my $uname (@existing) {
                   1816:                 my $userlink =
                   1817:                     &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
                   1818:                 $output .= '<li>'.$userlink.'</li>';
                   1819:             }
                   1820:             $output .= '</ul></p>';
1.1       raeburn  1821:         } else {
1.12      raeburn  1822:             $output .= '<p>'.&mt('The following course/community creation requests were deleted because the course or community has already been created:').'<ul>';
1.2       raeburn  1823:             foreach my $cnum (@existing) {
                   1824:                 my $showcourse;
                   1825:                 my %coursehash = &Apache::lonnet::coursedescription($cdom.'/'.$cnum);
                   1826:                 if ($coursehash{'description'} ne '') {
                   1827:                     $showcourse = $coursehash{'description'};
                   1828:                 } else {
                   1829:                     $showcourse = $cnum;
                   1830:                 }
                   1831:                 $output .= '<li>'.$showcourse.'</li>';
                   1832:             }
                   1833:             $output .= '</ul></p>';
1.1       raeburn  1834:         }
                   1835:     }
                   1836:     if (@missingreq) {
                   1837:         if ($context eq 'course') {
                   1838:             $output .= '<p>'.&mt('The following enrollment requests were ignored because the request is no longer in the enrollment queue:').'<ul>';
                   1839:             foreach my $user (@missingreq) {
                   1840:                 $output .= '<li>'.$user.'</li>';
                   1841:             }
                   1842:             $output .= '</ul></p>';
1.30      raeburn  1843:         } elsif ($context eq 'requestauthor') {
                   1844:             $output .= '<p>'.&mt('The following requests were ignored because the request is no longer in the queue:').'<ul>';
                   1845:             foreach my $uname (@missingreq) {
                   1846:                 my $userlink =
                   1847:                     &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
                   1848:                 $output .= '<li>'.$userlink.'</li>';
                   1849:             }
                   1850:             $output .= '</ul></p>';
1.2       raeburn  1851:         } else {
1.12      raeburn  1852:             $output .= '<p>'.&mt('The following course/community creation requests were ignored because the request is no longer in the queue:').'<ul>';
1.2       raeburn  1853:             foreach my $cnum (@missingreq) {
                   1854:                 $output .= '<li>'.$cnum.'</li>';
                   1855:             }
                   1856:             $output .= '</ul></p>';
1.1       raeburn  1857:         }
                   1858:     }
                   1859:     if (@invalidusers) {
                   1860:         if ($context eq 'course') {
                   1861:             $output .= '<p>'.&mt('The following enrollment requests were deleted because the requestor does not have a LON-CAPA account:').'<ul>';
                   1862:             foreach my $user (@invalidusers) {
                   1863:                 $output .= '<li>'.$user.'</li>';
                   1864:             }
                   1865:             $output .= '</ul></p>';
1.30      raeburn  1866:         } elsif ($context eq 'requestauthor') {
1.42      bisitz   1867:             $output .= '<p>'.&mt('The following Authoring Space requests were deleted because the requestor does not have a LON-CAPA account:').'<ul>';
1.30      raeburn  1868:             foreach my $uname (@invalidusers) {
                   1869:                 my $userlink =
                   1870:                     &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
                   1871:                 $output .= '<li>'.$userlink.'</li>';
                   1872:             }
                   1873:             $output .= '</ul></p>';
1.1       raeburn  1874:         }
                   1875:     }
                   1876:     if (@limitexceeded) {
                   1877:         if ($context eq 'course') {
                   1878:             $output .= '<p>'.&mt('The following enrollment requests were skipped because the enrollment limit has been reached for the course:').'<ul>';
                   1879:             foreach my $user (@limitexceeded) {
                   1880:                 $output .= '<li>'.$user.'</li>';
                   1881:             }
                   1882:             $output .= '</ul></p>';
                   1883:         }
                   1884:     }
1.5       raeburn  1885:     if (@nopermissions) {
1.30      raeburn  1886:         if ($context eq 'course') {
                   1887:             $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>';
                   1888:             foreach my $cnum (@nopermissions) {
                   1889:                 my $showcourse;
                   1890:                 if (ref($requesthash{$cnum.'_'.$queue})) {
                   1891:                     $showcourse = $requesthash{$cnum.'_'.$queue}{'description'};
                   1892:                 } else {
                   1893:                     $showcourse = $cnum;
                   1894:                 }
                   1895:                 $output .= '<li>'.$showcourse.'</li>';
                   1896:             }
                   1897:             $output .= '</ul></p>';
                   1898:         } elsif ($context eq 'requestauthor') {
1.42      bisitz   1899:             $output .= '<p>'.&mt('The following requests could not be processed because the requestor does not have rights to request an Authoring Space:').'<ul>';
1.30      raeburn  1900:             foreach my $uname (@nopermissions) {
                   1901:                 my $userlink =
                   1902:                     &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
                   1903:                 $output .= '<li>'.$userlink.'</li>';
1.5       raeburn  1904:             }
1.30      raeburn  1905:             $output .= '</ul></p>';
1.5       raeburn  1906:         }
                   1907:     }
1.2       raeburn  1908:     if (@processing_errors) {
1.1       raeburn  1909:         if ($context eq 'course') {
                   1910:             $output .= '<p>'.&mt('The following enrollment requests could not be processed because an error occurred:').'<ul>';
1.2       raeburn  1911:             foreach my $user (@processing_errors) {
1.1       raeburn  1912:                 $output .= '<li>'.$user.'</li>';
                   1913:             }
                   1914:             $output .= '</ul></p>';
1.30      raeburn  1915:         } elsif ($context eq 'requestauthor') {
                   1916:             $output .= '<p>'.&mt('The following requests could not be processed because an error occurred:').'<ul>';
                   1917:             foreach my $uname (@processing_errors) {
                   1918:                 my $userlink =
                   1919:                     &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
                   1920:                 $output .= '<li>'.$userlink.'</li>';
                   1921:             }
                   1922:             $output .= '</ul></p>';
1.43      raeburn  1923:         } elsif ($context eq 'requestusername') {
                   1924:             $output .= '<p>'.&mt('The following requests could not be processed because an error occurred:').'<ul>';
                   1925:             foreach my $uname (@processing_errors) {
                   1926:                 $output .= '<li>'.$uname.'</li>';
                   1927:             }
                   1928:             $output .= '</ul></p>';
1.1       raeburn  1929:         } else {
1.12      raeburn  1930:             $output .= '<p>'.&mt('The following course/community creation requests could not be processed because an error occurred:').'<ul>';
1.2       raeburn  1931:             foreach my $cnum (@processing_errors) {
                   1932:                 my $showcourse;
1.23      raeburn  1933:                 if (ref($requesthash{$cnum.'_'.$queue})) {
                   1934:                     $showcourse = $requesthash{$cnum.'_'.$queue}{'description'};
1.2       raeburn  1935:                 } else {
                   1936:                     $showcourse = $cnum;
                   1937:                 }
                   1938:                 $output .= '<li>'.$showcourse.'</li>';
                   1939:             }
                   1940:             $output .= '</ul></p>';
1.1       raeburn  1941:         }
                   1942:     }
1.3       raeburn  1943:     if (@rejectionerrors) {
1.12      raeburn  1944:         $output .= '<p>'.&mt('The following course/community creation request rejections could not be fully processed because an error occurred:').'<ul>';
1.3       raeburn  1945:         foreach my $cnum (@rejectionerrors) {
                   1946:             my $showcourse;
1.23      raeburn  1947:             if (ref($requesthash{$cnum.'_'.$queue})) {
                   1948:                 $showcourse = $requesthash{$cnum.'_'.$queue}{'description'};
1.3       raeburn  1949:             } else {
                   1950:                 $showcourse = $cnum;
                   1951:             }
                   1952:             $output .= '<li>'.$showcourse.'</li>';
                   1953:         }
                   1954:         $output .= '</ul></p>';
                   1955:     }
1.2       raeburn  1956:     if (@warn_approves || @warn_rejects) {
1.1       raeburn  1957:         if ($context eq 'course') {
                   1958:             $output .= '<p>'.&mt("For the following users, an error occurred when updating the user's own self-enroll requests record:").'<ul>';
                   1959:             foreach my $user (@warn_approves) {
                   1960:                 $output .= '<li>'.$user.'</li>';
                   1961:             }
                   1962:             $output .= '</ul></p>';
1.30      raeburn  1963:         } elsif ($context eq 'requestauthor') {
                   1964:             $output .= '<p>'.&mt("For the following users, an error occurred when updating the user's own author request record:").'<ul>';
                   1965:             foreach my $uname (@warn_approves,@warn_rejects) {
                   1966:                 my $userlink =
                   1967:                     &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
                   1968:                 $output .= '<li>'.$userlink.'</li>';
                   1969:             }
                   1970:             $output .= '</ul></p>';
1.43      raeburn  1971:         } elsif ($context eq 'requestusername') {
                   1972:             $output .= '<p>'.&mt("For the following users, an error occurred when updating the account request record for the user:").'<ul>';
                   1973:             foreach my $uname (@warn_approves,@warn_rejects) {
                   1974:                 $output .= '<li>'.$uname.'</li>';
                   1975:             }
                   1976:             $output .= '</ul></p>';
1.1       raeburn  1977:         } else {
1.12      raeburn  1978:             $output .= '<p>'.&mt("For the following course/community requests an error occurred when updating the requestor's own requests record:").'<ul>';
1.2       raeburn  1979:             foreach my $cnum (@warn_approves,@warn_rejects) {
                   1980:                 my $showcourse;
1.23      raeburn  1981:                 if (ref($requesthash{$cnum.'_'.$queue})) {
                   1982:                     $showcourse = $requesthash{$cnum.'_'.$queue}{'description'};
1.2       raeburn  1983:                 } else {
                   1984:                     $showcourse = $cnum;
                   1985:                 }
                   1986:                 $output .= '<li>'.$showcourse.'</li>';
1.1       raeburn  1987:             }
                   1988:             $output .= '</ul></p>';
                   1989:         }
                   1990:     }
1.19      raeburn  1991:     if (@warn_dels) {
1.30      raeburn  1992:         if ($context eq 'requestauthor') {
                   1993:             $output .= '<p>'.&mt("For the following requests an error occurred when removing the request from the queue:").'<ul>';
                   1994:             foreach my $uname (@warn_dels) {
                   1995:                 my $userlink =
                   1996:                     &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$cdom),$uname,$cdom);
                   1997:                 $output .= '<li>'.$userlink.'</li>';
                   1998:             }
                   1999:             $output .= '</ul></p>';
1.43      raeburn  2000:         } elsif ($context eq 'requestusername') {
                   2001:             $output .= '<p>'.&mt("For the following requests an error occurred when removing the request from the queue:").'<ul>';
                   2002:             foreach my $item (@warn_dels) {
                   2003:                 my ($escuname) = split(/_/,$item);
                   2004:                 $output .= '<li>'.&unescape($escuname).'</li>';
                   2005:             }
                   2006:             $output .= '</ul></p>';            
1.30      raeburn  2007:         } else {
1.36      bisitz   2008:             $output .= '<p>'.&mt("For the following course/community requests an error occurred when removing requests from the pending queue:").'<ul>';
1.30      raeburn  2009:             foreach my $cnum (@warn_dels) {
                   2010:                 my $showcourse;
                   2011:                 if (ref($requesthash{$cnum.'_'.$queue})) {
                   2012:                     $showcourse = $requesthash{$cnum.'_'.$queue}{'description'};
                   2013:                 } else {
                   2014:                     $showcourse = $cnum;
                   2015:                 }
                   2016:                 $output .= '<li>'.$showcourse.'</li>';
1.19      raeburn  2017:             }
1.30      raeburn  2018:             $output .= '</ul></p>';
1.19      raeburn  2019:         }
                   2020:     }
1.1       raeburn  2021:     return $output;
                   2022: }
                   2023: 
1.63    ! raeburn  2024: sub requester_roles {
        !          2025:     my ($requname,$requdom,$activeroles) = @_;
        !          2026:     if (ref($activeroles) eq 'HASH') {
        !          2027:         my %roleshash = &Apache::lonnet::get_my_roles($requname,$requdom,'userroles');
        !          2028:         $activeroles->{$requname.':'.$requdom} = \%roleshash;
        !          2029:     }
        !          2030:     return;
        !          2031: }
        !          2032: 
        !          2033: sub requester_has_perm {
        !          2034:     my ($crsdom,$crsnum,$mrole,$requesterroles) = @_;
        !          2035:     return unless (ref($requesterroles) eq 'HASH');
        !          2036:     my $has_perm;
        !          2037:     foreach my $key (keys(%{$requesterroles})) {
        !          2038:         if ($crsnum eq '') {
        !          2039:             next unless ($key =~ /^\Q:$crsdom:\E/);
        !          2040:         } else {
        !          2041:             next unless (($key =~ /^\Q$crsnum:$crsdom:\E/) || ($key =~ /^\Q:$crsdom:\E/));
        !          2042:         }
        !          2043:         my ($keycrs,$keydom,$keyrole) = split(/:/,$key);
        !          2044:         if (($keycrs ne '') && ($crsnum ne '')) {
        !          2045:             if ($keycrs eq $crsnum) {
        !          2046:                 if ($Apache::lonnet::pr{$keyrole.':c'} =~ /(^|:)c\Q$mrole\E(&|:)/) {
        !          2047:                     $has_perm = 1;
        !          2048:                     last;
        !          2049:                 }
        !          2050:             }
        !          2051:         } else {
        !          2052:             if ($Apache::lonnet::pr{$keyrole.':d'} =~ /(^|:)c\Q$mrole\E(&|:)/) {
        !          2053:                 $has_perm = 1;
        !          2054:                 last;
        !          2055:             }
        !          2056:         }
        !          2057:     }
        !          2058:     return $has_perm;
        !          2059: }
        !          2060: 
1.1       raeburn  2061: sub get_student_counts {
                   2062:     my ($cdom,$cnum) = @_;
                   2063:     my (%idx,%stucounts);
                   2064:     my $classlist = &Apache::loncoursedata::get_classlist($cdom,$cnum);
                   2065:     $idx{'type'} = &Apache::loncoursedata::CL_TYPE();
                   2066:     $idx{'status'} = &Apache::loncoursedata::CL_STATUS();
                   2067:     while (my ($student,$data) = each(%$classlist)) {
                   2068:         if (($data->[$idx{'status'}] eq 'Active') ||
                   2069:             ($data->[$idx{'status'}] eq 'Future')) {
                   2070:             if ($data->[$idx{'type'}] eq 'selfenroll') {
                   2071:                 $stucounts{'selfenroll'} ++;
                   2072:             }
                   2073:             $stucounts{'allstudents'} ++;
                   2074:         }
                   2075:     }
                   2076:     return (\%stucounts,\%idx,$classlist);
                   2077: }
                   2078: 
1.2       raeburn  2079: sub course_creation {
1.59      raeburn  2080:     my ($dom,$cnum,$context,$details,$logmsg,$clonemsg,$newusermsg,$addresult,
                   2081:         $enrollcount,$output,$keysmsg,$domdefs,$longroles,$coderef,$customhash,
                   2082:         $callercontext,$user_lh) = @_;
1.2       raeburn  2083:     unless ((ref($details) eq 'HASH') && (ref($domdefs) eq 'HASH') && 
                   2084:             (ref($longroles) eq 'HASH')) {
1.53      raeburn  2085:         return ('error: Invalid request');
1.2       raeburn  2086:     }
                   2087:     my ($result,$ownername,$ownerdom);
                   2088:     my $crstype = $details->{'crstype'};
1.41      raeburn  2089:     my $coursedesc = $details->{'cdescr'};
1.47      raeburn  2090:     my $accessstart = $details->{'accessstart'};
                   2091:     my $accessend = $details->{'accessend'};
                   2092:     my %domconfig = &Apache::lonnet::get_dom('configuration',['requestcourses'],$dom);
1.40      raeburn  2093:     if (ref($domconfig{'requestcourses'}) eq 'HASH') {
                   2094:         if (ref($domconfig{'requestcourses'}{'uniquecode'}) eq 'HASH') {
                   2095:             if ($domconfig{'requestcourses'}{'uniquecode'}{$crstype}) {
                   2096:                 $details->{'uniquecode'} = 1;
                   2097:             }
                   2098:         }
                   2099:     }
1.2       raeburn  2100:     if ($context eq 'domain') {
                   2101:         $ownername = $details->{'owner'};
                   2102:         $ownerdom  = $details->{'domain'};
                   2103:     } else {
                   2104:         $ownername = $env{'user.name'};
                   2105:         $ownerdom  = $env{'user.domain'};
                   2106:     }
1.41      raeburn  2107:     my $fullname = &Apache::loncommon::plainname($ownername,$ownerdom);
1.2       raeburn  2108:     my $owneremail;
                   2109:     my %emails = &Apache::loncommon::getemails($ownername,$ownerdom);
                   2110:     foreach my $email ('permanentemail','critnotification','notification') {
                   2111:         $owneremail = $emails{$email};
                   2112:         last if ($owneremail ne '');
                   2113:     }
1.61      raeburn  2114:     my %reqdetails = &build_batchcreatehash($dom,$cnum,$context,$details,$owneremail,$domdefs);
1.2       raeburn  2115:     my $cid = &LONCAPA::batchcreatecourse::build_course($dom,$cnum,'requestcourses',
1.59      raeburn  2116:                   \%reqdetails,$longroles,$logmsg,$clonemsg,$newusermsg,$addresult,
                   2117:                   $enrollcount,$output,$keysmsg,$ownerdom,$ownername,$cnum,$crstype,
                   2118:                   $coderef,$callercontext,$user_lh);
1.41      raeburn  2119:     my $postprocess;
1.2       raeburn  2120:     if ($cid eq "/$dom/$cnum") {
                   2121:         $result = 'created';
1.41      raeburn  2122:         my $code;
                   2123:         if (ref($coderef)) {
                   2124:             $code = $$coderef;
                   2125:         }
                   2126:         $postprocess = &Apache::lonnet::auto_crsreq_update($dom,$cnum,$crstype,$result,$ownername,
1.47      raeburn  2127:                                                            $ownerdom,$fullname,$coursedesc,$code,
                   2128:                                                            $accessstart,$accessend,$customhash);
1.2       raeburn  2129:     } else {
                   2130:         $result = 'error: '.$cid;
                   2131:     }
1.41      raeburn  2132:     return ($result,$postprocess);
1.2       raeburn  2133: }
                   2134: 
                   2135: sub build_batchcreatehash {
1.61      raeburn  2136:     my ($dom,$cnum,$context,$details,$owneremail,$domdefs) = @_;
1.2       raeburn  2137:     my %batchhash;
1.60      raeburn  2138:     my @items = qw{owner domain coursehome clonecrs clonedom datemode dateshift tinyurls enrollstart enrollend accessstart accessend sections users uniquecode};
1.2       raeburn  2139:     if ((ref($details) eq 'HASH') && (ref($domdefs) eq 'HASH')) {
1.17      raeburn  2140:         my $emailenc = &escape($owneremail);
1.2       raeburn  2141:         my $owner = $details->{'owner'}.':'.$details->{'domain'};
                   2142:         foreach my $item (@items) {
                   2143:             $batchhash{$item} = $details->{$item};
                   2144:         }
1.60      raeburn  2145:         if (ref($details->{'crosslists'}) eq 'HASH') {
                   2146:             foreach my $key (keys(%{$details->{'crosslists'}})) {
                   2147:                 if (ref($details->{'crosslists'}->{$key}) eq 'HASH') {
1.61      raeburn  2148:                     my $instsec = $details->{crosslists}->{$key}->{instsec};
                   2149:                     $batchhash{'crosslists'}{$key}{'inst'} = $details->{crosslists}->{$key}->{instcode};
                   2150:                     my $crskey = $cnum.':'.$batchhash{'crosslists'}{$key}{'inst'};
                   2151:                     my %formatted = &Apache::lonnet::auto_instsec_reformat($dom,'clutter',
                   2152:                                                                            {$crskey => [$instsec]});
                   2153:                     if (ref($formatted{$crskey}) eq 'ARRAY') {
                   2154:                         $batchhash{'crosslists'}{$key}{'inst'} .= $formatted{$crskey}->[0];
                   2155:                     }
1.60      raeburn  2156:                     $batchhash{'crosslists'}{$key}{'loncapa'} = $details->{crosslists}->{$key}->{loncapa};
                   2157:                 }
                   2158:             }
                   2159:         }
1.2       raeburn  2160:         $batchhash{'title'} = $details->{'cdescr'};
                   2161:         $batchhash{'coursecode'} = $details->{'instcode'};
1.35      raeburn  2162:         if ($domdefs->{'officialcredits'} || $domdefs->{'unofficialcredits'}) {
                   2163:             $batchhash{'defaultcredits'} = $details->{'defaultcredits'};
                   2164:         }
1.2       raeburn  2165:         $batchhash{'emailenc'} = $emailenc;
                   2166:         $batchhash{'adds'} = $details->{'autoadds'};
                   2167:         $batchhash{'drops'} = $details->{'autodrops'};
                   2168:         $batchhash{'authtype'} = $domdefs->{'auth_def'};
                   2169:         $batchhash{'authparam'} = $domdefs->{'auth_arg_def'};
                   2170:         if ($details->{'crstype'} eq 'community') {
                   2171:             $batchhash{'crstype'} = 'Community';
1.53      raeburn  2172:         } elsif ($details->{'crstype'} eq 'placement') {
                   2173:             $batchhash{'crstype'} = 'Placement';
1.2       raeburn  2174:         } else {
1.41      raeburn  2175:             if ($details->{'crstype'} eq 'textbook') {
                   2176:                 if ($details->{'clonecrs'} && $details->{'clonedom'}) {
                   2177:                     my %clonedfrom = &Apache::lonnet::coursedescription($details->{'clonedom'}.'_'.$details->{'clonecrs'});
                   2178:                     $batchhash{'textbook'} = $clonedfrom{'description'};
                   2179:                 }
1.62      raeburn  2180:             } elsif ($details->{'crstype'} eq 'lti') {
                   2181:                 $batchhash{'lti'} = 1;
1.41      raeburn  2182:             }
1.2       raeburn  2183:             $batchhash{'crstype'} = 'Course';
                   2184:         }
1.8       raeburn  2185:         my ($owner_firstname,$owner_lastname);
                   2186:         if ($context eq 'domain') {
                   2187:             my %userenv = &Apache::lonnet::userenvironment($details->{'domain'},
                   2188:                                                            $details->{'owner'},
                   2189:                                                            'firstname','lastname');
                   2190:             $owner_firstname = $userenv{'firstname'};
                   2191:             $owner_lastname = $userenv{'lastname'};
                   2192:         } else {
                   2193:             $owner_firstname = $env{'environment.firstname'};
                   2194:             $owner_lastname = $env{'environment.lastname'};
                   2195:         }
                   2196:         if (ref($details->{'personnel'}) eq 'HASH') {
                   2197:             %{$batchhash{'users'}} = %{$details->{'personnel'}};
                   2198:             if (ref($batchhash{'users'}) eq 'HASH') {  
                   2199:                 foreach my $userkey (keys(%{$batchhash{'users'}})) {
                   2200:                     if (ref($batchhash{'users'}{$userkey}) eq 'HASH') {
                   2201:                         if (ref($batchhash{'users'}{$userkey}{'roles'}) eq 'ARRAY') {
                   2202:                             foreach my $role (@{$batchhash{'users'}{$userkey}{'roles'}}) {
                   2203:                                 my $start = '';
                   2204:                                 my $end = '';
                   2205:                                 if ($role eq 'st') {
                   2206:                                     $start = $details->{'accessstart'};
                   2207:                                     $end = $details->{'accessend'};
                   2208:                                 }
                   2209:                                 $batchhash{'users'}{$userkey}{$role}{'start'} = $start;
                   2210:                                 $batchhash{'users'}{$userkey}{$role}{'end'} = $end;
                   2211:                             } 
                   2212:                         }
                   2213:                     }
                   2214:                 }
                   2215:             }
                   2216:         }
                   2217:         $batchhash{'users'}{$owner}{firstname} = $owner_firstname;
                   2218:         $batchhash{'users'}{$owner}{lastname} = $owner_lastname;
                   2219:         $batchhash{'users'}{$owner}{emailenc} = $emailenc;
                   2220:         $batchhash{'users'}{$owner}{owneremail} = $owneremail;
1.55      raeburn  2221:         $batchhash{'setcomment'} = 1;
1.2       raeburn  2222:     }
                   2223:     return %batchhash;
                   2224: }
                   2225: 
1.4       raeburn  2226: sub can_clone_course {
1.51      raeburn  2227:     my ($uname,$udom,$clonecrs,$clonedom,$crstype,$dom,$instcode) = @_;
1.4       raeburn  2228:     my $canclone;
1.11      raeburn  2229:     my $ccrole = 'cc';
1.12      raeburn  2230:     if ($crstype eq 'community') {
1.11      raeburn  2231:         $ccrole = 'co';
                   2232:     }
1.4       raeburn  2233:     my %roleshash = &Apache::lonnet::get_my_roles($uname,$udom,'userroles',['active'],
1.11      raeburn  2234:                                                   [$ccrole],[$clonedom]);
                   2235:     if (exists($roleshash{$clonecrs.':'.$clonedom.':'.$ccrole})) {
1.4       raeburn  2236:         $canclone = 1;
                   2237:     } else {
1.51      raeburn  2238:         my %courseenv = &Apache::lonnet::userenvironment($clonedom,$clonecrs,
                   2239:                                                          ('cloners','internal.coursecode'));
1.4       raeburn  2240:         my $cloners = $courseenv{'cloners'};
1.51      raeburn  2241:         my $clonefromcode = $courseenv{'internal.coursecode'};
1.4       raeburn  2242:         if ($cloners ne '') {
                   2243:             my @cloneable = split(',',$cloners);
                   2244:             if (grep(/^\*$/,@cloneable)) {
                   2245:                 $canclone = 1;
1.51      raeburn  2246:             } elsif (grep(/^\*:\Q$udom\E$/,@cloneable)) {
                   2247:                 $canclone = 1;
                   2248:             } elsif (grep(/^\Q$uname\E:\Q$udom\E$/,@cloneable)) {
                   2249:                 $canclone = 1;
1.4       raeburn  2250:             }
1.51      raeburn  2251:             unless ($canclone) {
                   2252:                 if (($clonefromcode) && ($instcode) && ($clonedom eq $dom)) {
                   2253:                     my (%gotdomdefaults,%gotcodedefaults);
                   2254:                     foreach my $cloner (@cloneable) {
                   2255:                         if (($cloner ne '*') && ($cloner !~ /^\*\:$match_domain$/) &&
                   2256:                             ($cloner !~ /^$match_username\:$match_domain$/) && ($cloner ne '')) {
                   2257:                             if ($cloner =~ /\=/) {
                   2258:                                 my (%codedefaults,@code_order);
                   2259:                                 if (ref($gotcodedefaults{$clonedom}) eq 'HASH') {
                   2260:                                     if (ref($gotcodedefaults{$clonedom}{'defaults'}) eq 'HASH') {
                   2261:                                         %codedefaults = %{$gotcodedefaults{$clonedom}{'defaults'}};
                   2262:                                     }
                   2263:                                     if (ref($gotcodedefaults{$clonedom}{'order'}) eq 'ARRAY') {
                   2264:                                         @code_order = @{$gotcodedefaults{$dom}{'order'}};
                   2265:                                     }
                   2266:                                 } else {
                   2267:                                     &Apache::lonnet::auto_instcode_defaults($clonedom,
                   2268:                                                                             \%codedefaults,
                   2269:                                                                             \@code_order);
                   2270:                                     $gotcodedefaults{$clonedom}{'defaults'} = \%codedefaults;
                   2271:                                     $gotcodedefaults{$clonedom}{'order'} = \@code_order;
                   2272:                                 }
                   2273:                                 if (@code_order > 0) {
                   2274:                                     if (&Apache::lonnet::check_instcode_cloning(\%codedefaults,\@code_order,
                   2275:                                                                                 $cloner,$clonefromcode,$instcode)) {
                   2276:                                         $canclone = 1;
                   2277:                                         last; 
                   2278:                                     }
                   2279:                                 }
                   2280:                             }
                   2281:                         }
                   2282:                     }
                   2283:                 }
1.4       raeburn  2284:             }
1.51      raeburn  2285:         } else {
                   2286:             my %domdefs = &Apache::lonnet::get_domain_defaults($clonedom);
                   2287:             if ($domdefs{'canclone'}) {
                   2288:                 unless ($domdefs{'canclone'} eq 'none') {
                   2289:                     if ($domdefs{'canclone'} eq 'domain') {
                   2290:                         if ($udom eq $clonedom) {
                   2291:                             $canclone = 1;
                   2292:                         }
                   2293:                     } elsif (($clonefromcode) && ($instcode) &&
                   2294:                              ($clonedom eq $dom)) {
                   2295:                         if (&Apache::lonnet::default_instcode_cloning($clonedom,$domdefs{'canclone'},
                   2296:                                                                       $clonefromcode,$instcode)) {
                   2297:                             $canclone = 1;
                   2298:                         }
                   2299:                     }
                   2300:                 }
1.4       raeburn  2301:             }
                   2302:         }
1.18      raeburn  2303:         unless ($canclone) {
                   2304:             if (&Apache::lonnet::is_course_owner($clonedom,$clonecrs,$uname,$udom)) {
1.20      bisitz   2305:                 $canclone = 1;
1.18      raeburn  2306:             }
                   2307:         }
1.4       raeburn  2308:     }
                   2309:     return $canclone;
                   2310: }
                   2311: 
1.13      raeburn  2312: sub get_processtype {
1.30      raeburn  2313:     my ($context,$uname,$udom,$isadv,$dom,$crstype,$inststatuses,$domconfig) = @_;
1.13      raeburn  2314:     return unless ((ref($inststatuses) eq 'ARRAY') && (ref($domconfig) eq 'HASH'));
                   2315:     if ($uname eq '' || $udom eq '') {
                   2316:         $uname = $env{'user.name'};
                   2317:         $udom = $env{'user.domain'};
                   2318:         $isadv = $env{'user.adv'};
                   2319:     }
1.30      raeburn  2320:     my (%userenv,%settings,$val,@options,$envkey);
                   2321:     if ($context eq 'course') {
                   2322:         @options = ('autolimit','validate','approval');
                   2323:         $envkey = 'requestcourses.'.$crstype;
                   2324:         if (ref($domconfig->{'requestcourses'}) eq 'HASH') {
                   2325:             if (ref($domconfig->{'requestcourses'}->{$crstype}) eq 'HASH') {
                   2326:                 %settings = %{$domconfig->{'requestcourses'}->{$crstype}};
                   2327:             }
                   2328:         }
                   2329:     } else {
                   2330:         @options = ('automatic','approval');
                   2331:         $envkey = 'requestauthor';
                   2332:         if (ref($domconfig->{'requestauthor'}) eq 'HASH') { 
                   2333:             %settings = %{$domconfig->{'requestauthor'}};
                   2334:         }
                   2335:     }
                   2336:     if (($dom eq $udom) || ($context eq 'requestauthor')) {
1.13      raeburn  2337:         %userenv =
1.30      raeburn  2338:             &Apache::lonnet::userenvironment($udom,$uname,$envkey,'inststatus');
                   2339:         if ($userenv{$envkey}) {
                   2340:             $val = $userenv{$envkey};
1.13      raeburn  2341:             @{$inststatuses} = ('_custom_');
                   2342:         } else {
1.30      raeburn  2343:             my %alltasks;
                   2344:             if (($isadv) && ($settings{'_LC_adv'} ne '')) {
1.33      raeburn  2345:                 $val = $settings{'_LC_adv'};
1.30      raeburn  2346:                 @{$inststatuses} = ('_LC_adv_');
                   2347:             } else {
                   2348:                 if ($userenv{'inststatus'} ne '') {
                   2349:                     @{$inststatuses} = split(',',$userenv{'inststatus'});
                   2350:                 } else {
                   2351:                     @{$inststatuses} = ('default');
                   2352:                 }
                   2353:                 foreach my $status (@{$inststatuses}) {
                   2354:                     if (exists($settings{$status})) {
                   2355:                         my $value = $settings{$status};
                   2356:                         next unless ($value);
                   2357:                         unless (exists($alltasks{$value})) {
                   2358:                             if (ref($alltasks{$value}) eq 'ARRAY') {
                   2359:                                 unless(grep(/^\Q$status\E$/,@{$alltasks{$value}})) {
                   2360:                                     push(@{$alltasks{$value}},$status);
1.13      raeburn  2361:                                 }
1.30      raeburn  2362:                             } else {
                   2363:                                 @{$alltasks{$value}} = ($status);
1.13      raeburn  2364:                             }
                   2365:                         }
1.30      raeburn  2366:                     }
                   2367:                 }
                   2368:                 my $maxlimit = 0;
                   2369:                 if ($context eq 'course') {
                   2370:                     foreach my $key (sort(keys(%alltasks))) {
                   2371:                         if ($key =~ /^autolimit=(\d*)$/) {
                   2372:                             if ($1 eq '') {
                   2373:                                 $val ='autolimit=';
                   2374:                                 last;
                   2375:                             } elsif ($1 > $maxlimit) {
                   2376:                                 $maxlimit = $1;
1.13      raeburn  2377:                             }
                   2378:                         }
1.30      raeburn  2379:                     }
                   2380:                 }
                   2381:                 if (($context eq 'requestauthor') || (!$val)) {
                   2382:                     if ($context eq 'course' && $maxlimit) {
                   2383:                         $val = 'autolimit='.$maxlimit;
                   2384:                     } else {
                   2385:                         foreach my $option (@options) {
                   2386:                             if ($alltasks{$option}) {
                   2387:                                 $val = $option;
                   2388:                                 last;
1.13      raeburn  2389:                             }
                   2390:                         }
                   2391:                     }
                   2392:                 }
                   2393:             }
                   2394:         }
                   2395:     } else {
                   2396:         %userenv = &Apache::lonnet::userenvironment($udom,$uname,'reqcrsotherdom.'.$crstype);
                   2397:         if ($userenv{'reqcrsotherdom.'.$crstype}) {
                   2398:             my @doms = split(',',$userenv{'reqcrsotherdom.'.$crstype});
                   2399:             my $optregex = join('|',@options);
                   2400:             foreach my $item (@doms) {
                   2401:                 my ($extdom,$extopt) = split(':',$item);
                   2402:                 if ($extdom eq $dom) {
                   2403:                     if ($extopt =~ /^($optregex)(=?\d*)$/) {
                   2404:                         $val = $1.$2;
                   2405:                     }
                   2406:                     last;
                   2407:                 }
                   2408:             }
                   2409:             @{$inststatuses} = ('_external_');
                   2410:         }
                   2411:     }
                   2412:     return $val;
                   2413: }
                   2414: 
1.14      raeburn  2415: sub queued_selfenrollment {
                   2416:     my ($notitle) = @_;
                   2417:     my $output;
                   2418:     my %selfenrollrequests = &Apache::lonnet::dump('selfenrollrequests');
                   2419:     my %reqs_by_date;
                   2420:     foreach my $item (keys(%selfenrollrequests)) {
                   2421:         if (ref($selfenrollrequests{$item}) eq 'HASH') {
                   2422:             if ($selfenrollrequests{$item}{'status'} eq 'request') {
                   2423:                 if ($selfenrollrequests{$item}{'timestamp'}) {
                   2424:                     push(@{$reqs_by_date{$selfenrollrequests{$item}{'timestamp'}}},$item);
                   2425:                 }
                   2426:             }
                   2427:         }
                   2428:     }
                   2429:     if (keys(%reqs_by_date)) {
                   2430:         unless ($notitle) {
1.32      raeburn  2431:             $output .= '<br /><b>'.&mt('Enrollment requests pending Course Coordinator approval').'</b><br />';
1.14      raeburn  2432:         }
                   2433:         $output .= &Apache::loncommon::start_data_table().
                   2434:                    &Apache::loncommon::start_data_table_header_row().
                   2435:                    '<th>'.&mt('Date requested').'</th><th>'.&mt('Course title').'</th>'.
                   2436:                    '<th>'.&mt('User role').'</th><th>'.&mt('Section').'</th>'.
                   2437:                    &Apache::loncommon::end_data_table_header_row();
                   2438:         my @sorted = sort { $a <=> $b } (keys(%reqs_by_date));
                   2439:         foreach my $item (@sorted) {
                   2440:             if (ref($reqs_by_date{$item}) eq 'ARRAY') {
                   2441:                 foreach my $crs (@{$reqs_by_date{$item}}) {
                   2442:                     my %courseinfo = &Apache::lonnet::coursedescription($crs);
                   2443:                     my $usec = $selfenrollrequests{$crs}{'section'};
1.16      raeburn  2444:                     my $rolename = &Apache::lonnet::plaintext('st',$courseinfo{'type'},$crs);
1.14      raeburn  2445:                     if ($usec eq '') {
                   2446:                         $usec = &mt('No section');
                   2447:                     }
                   2448:                     $output .= &Apache::loncommon::start_data_table_row().
                   2449:                                '<td>'.&Apache::lonlocal::locallocaltime($item).'</td>'.
                   2450:                                '<td>'.$courseinfo{'description'}.'</td>'.
                   2451:                                '<td>'.$rolename.'</td><td>'.$usec.'</td>'.
                   2452:                                &Apache::loncommon::end_data_table_row();
                   2453:                 }
                   2454:             }
                   2455:         }
                   2456:         $output .= &Apache::loncommon::end_data_table();
                   2457:     }
                   2458:     return $output;
                   2459: }
                   2460: 
1.19      raeburn  2461: sub update_coursereq_status {
1.26      raeburn  2462:     my ($reqhash,$dom,$cnum,$reqstatus,$context,$udom,$uname) = @_;
1.19      raeburn  2463:     my ($storeresult,$statusresult,$output);
                   2464:     my $requestkey = $dom.'_'.$cnum;
                   2465:     if ($requestkey =~ /^($match_domain)_($match_courseid)$/) {
                   2466:         $storeresult = &Apache::lonnet::store_userdata($reqhash,$requestkey,
1.26      raeburn  2467:                                                        'courserequests',$udom,$uname);
1.19      raeburn  2468:         if ($storeresult eq 'ok') {
                   2469:             my %status = (
                   2470:                              'status:'.$dom.':'.$cnum => $reqstatus,
                   2471:                          );
1.26      raeburn  2472:             $statusresult = &Apache::lonnet::put('courserequests',\%status,$udom,$uname);
1.19      raeburn  2473:         }
                   2474:     } else {
                   2475:         $storeresult = 'error: invalid requestkey format';
                   2476:     }
                   2477:     if ($storeresult ne 'ok') {
                   2478:         $output = &mt('An error occurred saving a record of the details of your request: [_1].',$storeresult);
                   2479:         if ($context eq 'domain') {
                   2480:             $output .= "\n";  
                   2481:         } else {
                   2482:             $output =  '<span class="LC_warning">'.$output.'</span><br />';
                   2483:         }
1.26      raeburn  2484:         &Apache::lonnet::logthis("Error saving course request - $requestkey for $uname:$udom - $storeresult");
1.19      raeburn  2485:     } elsif ($statusresult ne 'ok') {
                   2486:         $output = &mt('An error occurred saving a record of the status of your request: [_1].',$statusresult);
                   2487:         if ($context eq 'domain') {
                   2488:             $output .= "\n";
                   2489:         } else {
                   2490:             $output = '<span class="LC_warning">'.$output.'</span><br />';
                   2491:         }
1.26      raeburn  2492:         &Apache::lonnet::logthis("Error saving course request status for $requestkey (for $uname:$udom) - $statusresult");
1.19      raeburn  2493:     }
                   2494:     return ($storeresult,$output);
                   2495: }
                   2496: 
1.23      raeburn  2497: sub process_official_reqs {
1.26      raeburn  2498:     my ($context,$dom,$dcname,$dcdom) = @_;
1.23      raeburn  2499:     my $reqsnamespace = 'courserequestqueue';
                   2500:     my %requesthash =
1.24      raeburn  2501:         &Apache::lonnet::dump_dom($reqsnamespace,$dom,'_pending');
1.23      raeburn  2502:     my (%newcids,%longroles,%stillpending);
                   2503:     my @courseroles = ('cc','in','ta','ep','ad','st');
                   2504:     foreach my $role (@courseroles) {
                   2505:         $longroles{$role}=&Apache::lonnet::plaintext($role);
                   2506:     }
                   2507:     my %domdefs = &Apache::lonnet::get_domain_defaults($dom);
1.59      raeburn  2508:     my ($output,$linefeed,$user_lh);
1.23      raeburn  2509:     if ($context eq 'auto') {
                   2510:         $linefeed = "\n";
1.59      raeburn  2511:         $user_lh = &Apache::loncommon::user_lang($dcname,$dcdom);
1.23      raeburn  2512:     } else {
                   2513:         $linefeed = '<br />'."\n";
                   2514:     }
                   2515:     foreach my $key (keys(%requesthash)) {
                   2516:         my ($cnum,$status) = split('_',$key);
                   2517:         next if (&Apache::lonnet::homeserver($cnum,$dom) ne 'no_host');
                   2518:         if (ref($requesthash{$key}) eq 'HASH') {
                   2519:             my $ownername = $requesthash{$key}{'ownername'};
                   2520:             my $ownerdom = $requesthash{$key}{'ownerdom'};
                   2521:             next if (&Apache::lonnet::homeserver($ownername,$ownerdom) eq 'no_host');
                   2522:             my $inststatus;
                   2523:             my %userenv =
                   2524:                 &Apache::lonnet::get('environment',['inststatus'],
                   2525:                                      $ownerdom,$ownername);
                   2526:             my ($tmp) = keys(%userenv);
                   2527:             if ($tmp !~ /^(con_lost|error|no_such_host)/i) {
                   2528:                 $inststatus = $userenv{'inststatus'};
                   2529:             } else {
                   2530:                 undef(%userenv);
                   2531:             }
                   2532:             my $reqkey = $dom.'_'.$cnum;
                   2533:             my %history = &Apache::lonnet::restore($reqkey,'courserequests',
                   2534:                                                    $ownerdom,$ownername);
                   2535:             if (ref($history{'details'}) eq 'HASH') {
                   2536:                 my $instcode = $history{'details'}{'instcode'};
                   2537:                 my $crstype = $history{'details'}{'crstype'};
                   2538:                 my $reqtime = $history{'details'}{'reqtime'};
                   2539:                 my $cdescr = $history{'details'}{'cdescr'};
                   2540:                 my @currsec;
                   2541:                 my $sections = $history{'details'}{'sections'};
                   2542:                 if (ref($sections) eq 'HASH') {
                   2543:                     foreach my $i (sort(keys(%{$sections}))) {
                   2544:                         if (ref($sections->{$i}) eq 'HASH') {
                   2545:                             my $sec = $sections->{$i}{'inst'};
                   2546:                             if (!grep(/^\Q$sec\E$/,@currsec)) {
                   2547:                                 push(@currsec,$sec);
                   2548:                             }
                   2549:                         }
                   2550:                     }
                   2551:                 }
                   2552:                 my $instseclist = join(',',@currsec);
                   2553:                 my ($validationchk,$disposition,$reqstatus,$message,
                   2554:                     $validation,$validationerror);
                   2555:                 $validationchk =
                   2556:                     &Apache::lonnet::auto_courserequest_validation($dom,
                   2557:                         $ownername.':'.$ownerdom,$crstype,$inststatus,
                   2558:                         $instcode,$instseclist);
                   2559:                 if ($validationchk =~ /:/) {
                   2560:                     ($validation,$message) = split(':',$validationchk);
                   2561:                 } else {
                   2562:                     $validation = $validationchk;
                   2563:                 }
                   2564:                 if ($validation =~ /^error(.*)$/) {
                   2565:                     $disposition = 'approval';
                   2566:                     $validationerror = $1;
                   2567:                 } else {
                   2568:                     $disposition = $validation;
                   2569:                 }
                   2570:                 $reqstatus = $disposition;
                   2571:                 if ($disposition eq 'process') {
1.39      raeburn  2572:                     my ($logmsg,$newusermsg,$addresult,$enrollcount,$response,$keysmsg,$code);
1.59      raeburn  2573:                     my $clonemsg = [];
1.41      raeburn  2574:                     my %customitems;
                   2575:                     my $fullname = &Apache::loncommon::plainname($ownername,$ownerdom);
                   2576:                     my $inprocess = &Apache::lonnet::auto_crsreq_update($dom,$cnum,$crstype,'process',$ownername,
                   2577:                                                                         $ownerdom,$fullname,$cdescr);
                   2578:                     if (ref($inprocess) eq 'HASH') {
                   2579:                         foreach my $key (keys(%{$inprocess})) {
                   2580:                             if (exists($history{'details'}{$key})) {
                   2581:                                 $customitems{$key} = $history{'details'}{$key};
                   2582:                             }
                   2583:                         }
                   2584:                     }
1.50      raeburn  2585:                     if ($history{'details'}{'clonecrs'}) {
                   2586:                         $customitems{'_LC_clonefrom'} = $history{'details'}{'clonedom'}.'_'.$history{'details'}{'clonecrs'};
                   2587:                     }
1.41      raeburn  2588:                     my ($result,$postprocess) = 
1.59      raeburn  2589:                         &course_creation($dom,$cnum,'domain',$history{'details'},\$logmsg,$clonemsg,\$newusermsg,
                   2590:                                          \$addresult,\$enrollcount,\$response,\$keysmsg,\%domdefs,\%longroles,
                   2591:                                          \$code,\%customitems,$context,$user_lh);
1.23      raeburn  2592:                     if ($result eq 'created') {
                   2593:                         $disposition = 'created';
                   2594:                         $reqstatus = 'created';
1.26      raeburn  2595:                         my $cid = $dom.'_'.$cnum;
                   2596:                         push(@{$newcids{$instcode}},$cid);
                   2597:                         if ($dcname && $dcdom) {
1.54      raeburn  2598:                             my $firsturl = &Apache::lonnet::course_portal_url($cnum,$dom);
1.26      raeburn  2599:                             my $beneficiary = 'pendingrequestor';
                   2600:                             my $now = time;
                   2601:                             my $owner = $ownername.':'.$ownerdom;
                   2602:                             my $approvedmsg =
                   2603:                                 [{
1.27      raeburn  2604:                                     mt => 'Your requested course: [_1], (queued pending validation) has now been created.',
                   2605:                                     args => [$cdescr],
1.59      raeburn  2606:                                  }];
                   2607:                             if ((ref($clonemsg) eq 'ARRAY') && (@{$clonemsg})) {
                   2608:                                 push(@{$approvedmsg},@{$clonemsg});
                   2609:                             }
                   2610:                             push(@{$approvedmsg},
1.26      raeburn  2611:                                  {
1.28      raeburn  2612:                                     mt   => 'Visit [_1] to log-in and access the course.',
1.26      raeburn  2613:                                     args => [$firsturl],
1.27      raeburn  2614:                                  },
                   2615:                                  {
1.59      raeburn  2616:                                     mt => 'If currently logged-in to LON-CAPA, log-out and log-in again to select your new course role.',
                   2617:                                     args => [],
                   2618:                                  }
                   2619:                             );
1.26      raeburn  2620:                             my $sender = $dcname.':'.$dcdom;
1.41      raeburn  2621:                             if (ref($postprocess) eq 'HASH') {
                   2622:                                 if (ref($postprocess->{'createdmsg'}) eq 'ARRAY') {
                   2623:                                     foreach my $item (@{$postprocess->{'createdmsg'}}) {
                   2624:                                         if (ref($item) eq 'HASH') {
                   2625:                                              if ($item->{'mt'} ne '') {
                   2626:                                                  push(@{$approvedmsg},$item);
                   2627:                                              }
                   2628:                                         }
                   2629:                                     }
                   2630:                                 }
1.48      raeburn  2631:                                 if (ref($postprocess->{'createdactions'}) eq 'HASH') {
                   2632:                                     if (ref($postprocess->{'createdactions'}{'environment'}) eq 'HASH') {
                   2633:                                         &postprocess_crsenv($dom,$cnum,$postprocess->{'createdactions'}{'environment'});
                   2634:                                     }
                   2635:                                 }
1.41      raeburn  2636:                             }
1.26      raeburn  2637:                             &send_selfserve_notification($owner,$approvedmsg,
                   2638:                                                          $cid,$cdescr,$now,
                   2639:                                                          $beneficiary,$sender,
                   2640:                                                          undef,undef,$crstype);
                   2641:                         }
1.23      raeburn  2642:                     }
                   2643:                 } elsif ($disposition eq 'rejected') {
                   2644:                     $output .= &mt('Queued course request for [_1] submitted by [_2] with status [_3] rejected when validating.',$instcode,$ownername.':'.$ownerdom,$inststatus).$linefeed;
                   2645:                 } elsif ($disposition eq 'approval') {
                   2646:                     $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;
                   2647: 
                   2648:                     my $requestid = $cnum.'_'.$disposition;
                   2649:                     my $request = {
                   2650:                             $requestid => {
                   2651:                                             timestamp   => $reqtime,
                   2652:                                             crstype     => $crstype,
                   2653:                                             ownername   => $ownername,
                   2654:                                             ownerdom    => $ownerdom,
                   2655:                                             description => $cdescr,
                   2656:                                           },
                   2657:                           };
                   2658:                     my $putresult = &Apache::lonnet::newput_dom('courserequestqueue',$request,$dom);
                   2659:                     unless ($putresult eq 'ok') {
                   2660:                         $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;
                   2661:                     }
                   2662:                 } elsif ($disposition eq 'pending') {
                   2663:                     my $instcode = $requesthash{$key}{'instcode'};
                   2664:                     my $description = $requesthash{$key}{'description'};
                   2665:                     my $timestamp = $requesthash{$key}{'timestamp'};
                   2666:                     my $entry = $cnum.':'.$ownername.':'.$ownerdom.':'.
                   2667:                                 $instcode.':'.$description;
                   2668:                     if (ref($stillpending{$timestamp}) eq 'ARRAY') {
                   2669:                         push(@{$stillpending{$timestamp}},$entry);
                   2670:                     } else {
                   2671:                         $stillpending{$timestamp} = [$entry];
                   2672:                     }
                   2673:                 }
                   2674:                 unless ($disposition eq 'pending') {
                   2675:                     my ($statusresult,$output) =
                   2676:                         &update_coursereq_status(\%requesthash,$dom,$cnum,
1.26      raeburn  2677:                                                  $reqstatus,'domain',$ownerdom,
                   2678:                                                  $ownername);
1.23      raeburn  2679:                     unless (&Apache::lonnet::del_dom($reqsnamespace,[$cnum.'_pending'],$dom) eq 'ok') {
                   2680:                         $output .= &mt('An error occurred when removing the request for [_1] submitted by [_2] from the pending queue.',$instcode,$ownername.':'.$ownerdom).$linefeed;
                   2681:                     }
                   2682:                 }
                   2683:             }
                   2684:         }
                   2685:     }
                   2686:     foreach my $key (sort(keys(%newcids))) {
                   2687:         if (ref($newcids{$key}) eq 'ARRAY') {
                   2688:             $output .= "created course from queued request: $key - ".join(', ',@{$newcids{$key}}).$linefeed;
                   2689:             my $newcourse = &LONCAPA::escape($key.':'.$newcids{$key});
                   2690:         }
                   2691:     }
                   2692:     unless ($context eq 'auto') {
                   2693:         if (keys(%stillpending) > 0) {
                   2694:             $output .= '<form method="post" name="changequeue" action="/adm/createcourse" />'."\n".
                   2695:                        '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />'."\n".
                   2696:                        '<input type="hidden" name="phase" value="requestchange" />'.
                   2697:                        '<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>'.
                   2698:                        &build_queue_display($dom,'stillpending',\%stillpending).
                   2699:                        '<br /><input type="hidden" name="queue" value="pending" />'."\n".
                   2700:                        '<input type="submit" name="processqueue" value="'.&mt('Save').'" />'.
                   2701:                        '</form>';
                   2702:         }
                   2703:     }
                   2704:     return $output;
                   2705: }
                   2706: 
1.48      raeburn  2707: sub postprocess_crsenv {
                   2708:     my ($dom,$cnum,$postprocessenv) = @_;
                   2709:     if (ref($postprocessenv) eq 'HASH') {    
                   2710:         my $cid = $dom.'_'.$cnum;
                   2711:         my %settablecrsenv = (
                   2712:                               'internal.selfenroll_types'        => 1,
                   2713:                               'internal.selfenroll_registered'   => 1,
                   2714:                               'internal.selfenroll_section'      => 1,
                   2715:                               'internal.selfenroll_start_access' => 1,
                   2716:                               'internal.selfenroll_end_access'   => 1,
                   2717:                               'internal.selfenroll_limit'        => 1,
                   2718:                               'internal.selfenroll_cap'          => 1,
                   2719:                               'internal.selfenroll_approval'     => 1,
                   2720:                               'internal.selfenroll_notifylist'   => 1,
                   2721:                              );
                   2722:         my %needcrsidput = (
                   2723:                               'internal.selfenroll_types'      => 1,
                   2724:                               'internal.selfenroll_start_date' => 1,
                   2725:                               'internal. selfenroll_end_date'  => 1,
                   2726:                            );
                   2727:         my (@needupdate,%newcrsenv);
                   2728:         foreach my $key (keys(%{$postprocessenv})) { 
                   2729:             if ($settablecrsenv{$key}) {
                   2730:                 $newcrsenv{$key} = $postprocessenv->{$key};
                   2731:                 if ($needcrsidput{$key}) {
                   2732:                     push(@needupdate,$key); 
                   2733:                 }
                   2734:             }
                   2735:             if (keys(%newcrsenv)) {
                   2736:                 my $putresult = &Apache::lonnet::put('environment',\%newcrsenv,$dom,$cnum);
                   2737:                 if ($putresult eq 'ok') {
                   2738:                     if (@needupdate) {
                   2739:                         my %crsinfo =
                   2740:                             &Apache::lonnet::courseiddump($dom,'.',1,'.','.',$cnum,undef,undef,'.');
                   2741:                         if (ref($crsinfo{$cid}) eq 'HASH') {
                   2742:                             foreach my $key (@needupdate) {
                   2743:                                 $crsinfo{$cid}{$key} = $newcrsenv{$key};
                   2744:                             }
                   2745:                             my $chome = &Apache::lonnet::homeserver($cnum,$dom);
                   2746:                             &Apache::lonnet::courseidput($dom,\%crsinfo,$chome,'notime');
                   2747:                         }
                   2748:                     }
                   2749:                 }
                   2750:             }
                   2751:         }
                   2752:     }
                   2753:     return;
                   2754: }
                   2755: 
                   2756: 
1.45      raeburn  2757: sub requestcourses_validation_types {
                   2758:     my @items = ('url','fields','button','markup');
                   2759:     my %names =  &Apache::lonlocal::texthash (
                   2760:             url      => 'Web address of validation server/script',
                   2761:             fields   => 'Form fields to send to validator',
                   2762:             button   => 'Text for validation button',
                   2763:             markup   => 'Validation description (HTML)',
                   2764:     );
                   2765:     my @fields = ('owner','course','coursetype','description');
                   2766:     return (\@items,\%names,\@fields);
                   2767: }
                   2768: 
1.31      raeburn  2769: sub is_active_author {
                   2770:     if ($env{'user.role.au./'.$env{'user.domain'}.'/'} =~ /^(\d*)\.(\d*)$/) {
                   2771:         if ((!$1 || $1 < time) &&
                   2772:             (!$2 || $2 > time)) {
                   2773:             return 1;
                   2774:         }
                   2775:     }
                   2776: }
                   2777: 
                   2778: sub author_prompt {
                   2779:     my ($is_active_author,$offer_author);
                   2780:     if ($env{'environment.canrequest.author'}) {
                   2781:         unless (&is_active_author()) {
1.32      raeburn  2782:             unless (&reqauthor_check() =~ /^approval:\d+$/) {
                   2783:                 $offer_author = 1;
1.31      raeburn  2784:             }
                   2785:         }
                   2786:     }
                   2787:     return $offer_author;
                   2788: }
                   2789: 
                   2790: sub reqauthor_check {
                   2791:     my $queued = $env{'environment.requestauthorqueued'};
                   2792:     my %reqauthor = &Apache::lonnet::get('requestauthor',['author_status','author'],
                   2793:                                          $env{'user.domain'},$env{'user.name'});
                   2794:     my $reqstatus = $reqauthor{'author_status'};
                   2795:     if (($reqstatus eq '' && $queued ne '') ||
                   2796:         ($env{'environment.requestauthorqueued'} !~ /^\Q$reqstatus\E/)) {
                   2797:         if (ref($reqauthor{'author'}) eq 'HASH') {
                   2798:             $queued = $reqstatus.':'.$reqauthor{'author'}{'timestamp'};
                   2799:         } else {
                   2800:             undef($queued);
                   2801:         }
                   2802:         &Apache::lonnet::appenv({'environment.requestauthorqueued' => $queued});
                   2803:     }
                   2804:     return $queued;
                   2805: }
                   2806: 
                   2807: sub process_reqauthor {
                   2808:     my ($dispositionref,$updateref) = @_;
                   2809:     if (&is_active_author()) {
                   2810:         return '<span class="LC_warning">'.
1.42      bisitz   2811:                 &mt('An Authoring Space has already been assigned to you.').'<br />'.
1.31      raeburn  2812:                 &mt('Please select the Author role from your [_1]roles page[_2].','<a href="/adm/roles">',
                   2813:                 '</a>').'</span>';
                   2814:     }
                   2815:     unless ($env{'environment.canrequest.author'}) {
                   2816:         return '<span class="LC_warning">'.
1.42      bisitz   2817:                 &mt('You do not currently have rights to request an Authoring Space.').'<br />'.
1.37      raeburn  2818:                 &mt('Please contact the [_1]helpdesk[_2] for assistance.','<a href="/adm/helpdesk">',
1.31      raeburn  2819:                 '</a>').'</span>';
                   2820:     }
                   2821:     my $queued = &reqauthor_check();
                   2822:     if ($queued =~ /^approval:(\d+)$/) {
                   2823:         my $timestamp = $1;
                   2824:         return '<span class="LC_info">'.
1.42      bisitz   2825:                &mt('A request for Authoring Space submitted on [_1] is awaiting approval',
1.31      raeburn  2826:                &Apache::lonlocal::locallocaltime($timestamp)).
                   2827:                '</span>';
                   2828:     } elsif ($queued =~ /^approved:(\d+)$/) {
                   2829:         my $timestamp = $1;   
                   2830:         my %roleshash = &Apache::lonnet::get_my_roles($env{'user.name'},$env{'user.domain'},'userroles',
                   2831:                                                       ['active'],['au'],[$env{'user.domain'}]);
                   2832:         if (keys(%roleshash) > 0) {
                   2833:             return '<span class="LC_info">'.
1.42      bisitz   2834:                    &mt('A request for Authoring Space submitted on [_1] has been approved.',
1.31      raeburn  2835:                    &Apache::lonlocal::locallocaltime($timestamp)).
                   2836:                    '</span>';
                   2837:         }
                   2838:     }
                   2839:     my ($output,@inststatuses,%domconfig);
                   2840:     %domconfig = &Apache::lonnet::get_dom('configuration',['requestauthor'],
                   2841:                                           $env{'user.domain'});
                   2842:     my $val = &get_processtype('requestauthor',$env{'user.name'},$env{'user.domain'},
                   2843:                                $env{'user.adv'},$env{'user.domain'},undef,
                   2844:                                \@inststatuses,\%domconfig);
                   2845:     my $now = time;
                   2846:     if ($val eq 'automatic') {
                   2847:         my $start = $now-1;
                   2848:         if (&Apache::lonnet::assignrole($env{'user.domain'},$env{'user.name'},'/'.$env{'user.domain'}.'/',
                   2849:                                         'au',undef,$start,undef,undef,'requestauthor') eq 'ok') {
                   2850:             $output = '<span class="LC_info">'.
1.42      bisitz   2851:                       &mt('Access to Authoring Space has been activated').'</span><br />';
1.31      raeburn  2852:                       &Apache::lonroles::update_session_roles();
                   2853:             &Apache::lonnet::appenv({'user.update.time'  => $now});
                   2854:             if (ref($updateref)) {
                   2855:                 $$updateref = $now;
                   2856:             }
                   2857:             if (ref($dispositionref)) {
                   2858:                 $$dispositionref = 'created';
                   2859:             }
                   2860:         } else {
                   2861:             $output = '<span class="LC_info">'.
1.42      bisitz   2862:                       &mt('An error occurred while activating your access to Authoring Space');
1.31      raeburn  2863:         }
                   2864:     } elsif ($val eq 'approval') {
                   2865:         my $domconfiguser = &Apache::lonnet::get_domainconfiguser($env{'user.domain'});
                   2866:         if (&Apache::lonnet::put('requestauthorqueue',{ $env{'user.name'}.'_'.$val => $now },
                   2867:                                  $env{'user.domain'},$domconfiguser) eq 'ok') {
                   2868:             my %userrequest = (
                   2869:                 author => {
                   2870:                             timestamp   => $now,
                   2871:                             status      => $val,
                   2872:                           },
                   2873:                 author_status => $val,
                   2874:             );
                   2875:             my $req_notifylist;
                   2876:             if (ref($domconfig{'requestauthor'}) eq 'HASH') {
                   2877:                 if (ref($domconfig{'requestauthor'}{'notify'}) eq 'HASH') {
                   2878:                     my $req_notifylist = $domconfig{'requestauthor'}{'notify'}{'approval'};
                   2879:                     if ($req_notifylist) {
                   2880:                         my $fullname = &Apache::loncommon::plainname($env{'user.name'},
                   2881:                                                                      $env{'user.domain'});
                   2882:                         my $sender = $env{'user.name'}.':'.$env{'user.domain'};
                   2883:                         my $domdesc = &Apache::lonnet::domain($env{'user.domain'},'description');
                   2884:                         &send_selfserve_notification($req_notifylist,
                   2885:                                                      "$fullname ($env{'user.name'}:$env{'user.domain'})",
                   2886:                                                      undef,$domdesc,$now,'authorreq',$sender);
                   2887:                     }
                   2888:                 }
                   2889:             }
                   2890:             my $userresult =
                   2891:                 &Apache::lonnet::put('requestauthor',\%userrequest,$env{'user.domain'},$env{'user.name'});
                   2892:             $output = '<span class="LC_info">'.
1.42      bisitz   2893:                       &mt('Your request for Authoring Space has been submitted for approval.').
1.31      raeburn  2894:                       '</span>';
                   2895:             &Apache::lonnet::appenv({'environment.requestauthorqueued' => $val.':'.$now});
                   2896:         } else {
                   2897:             $output = '<span class="LC_info">'.
1.42      bisitz   2898:                       &mt('An error occurred saving your request for Authoring Space.').
1.31      raeburn  2899:                       '</span>';
                   2900:         }
                   2901:     }
                   2902:     return $output;
                   2903: }
                   2904: 
1.1       raeburn  2905: 1;

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