--- loncom/interface/selfenroll.pm	2009/02/05 12:27:21	1.15
+++ loncom/interface/selfenroll.pm	2014/04/04 23:06:32	1.30
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Allow users to self-enroll in a course
 #
-# $Id: selfenroll.pm,v 1.15 2009/02/05 12:27:21 raeburn Exp $
+# $Id: selfenroll.pm,v 1.30 2014/04/04 23:06:32 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -34,6 +34,8 @@ use Apache::lonnet;
 use Apache::loncommon;
 use Apache::lonlocal;
 use Apache::createaccount;
+use Apache::loncoursequeueadmin;
+use Apache::lonuserutils;
 use LONCAPA qw(:DEFAULT :match);
 
 sub handler {
@@ -53,9 +55,11 @@ sub handler {
     &Apache::lonlocal::get_language_handle($r);
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['courseid']);
     my $js = &Apache::createaccount::catreturn_js();
-    my ($coursechk,$courseid) = &validate_course_id($env{'form.courseid'});
-    if ($coursechk ne 'ok') {
-        &page_header($r,$courseid,$js);
+
+    my $courseid = Apache::lonnet::is_course($env{'form.courseid'});
+
+    unless ($courseid) {
+        &page_header($r,$env{'form.courseid'},$js);
         $r->print('<h3>'.&mt('Self-enrollment error').'</h3>'.
                   '<span class="LC_error">'.
                   &mt('Invalid domain or course number').'</span>');
@@ -80,7 +84,7 @@ sub handler {
         $knownuser,$selfenroll_access_start,$selfenroll_access_end,
         $selfenroll_section,$selfenroll_future,%curr_role,$cdomdesc,
         $selfenroll_approval,$selfenroll_limit,$selfenroll_cap,
-        $selfenroll_notifylist,$owner);
+        $selfenroll_notifylist,$owner,$crstype);
     $selfenroll_types = $coursehash{'internal.selfenroll_types'};
     $selfenroll_registered =  $coursehash{'internal.selfenroll_registered'};
     $selfenroll_section = $coursehash{'internal.selfenroll_section'};
@@ -91,6 +95,10 @@ sub handler {
     $selfenroll_approval = $coursehash{'internal.selfenroll_approval'};
     $selfenroll_notifylist = $coursehash{'internal.selfenroll_notifylist'};
     $owner = $coursehash{'internal.courseowner'};
+    $crstype = $coursehash{'internal.type'};
+    if ($crstype eq '') {
+        $crstype = 'Course';
+    }
     my $nospace;
     if ($selfenroll_types ne '') {
         my $start = $coursehash{'internal.selfenroll_start_date'};
@@ -224,7 +232,7 @@ sub handler {
         &process_self_enroll($r,$cdom,$cnum,$selfenroll_types,$selfenroll_registered,
                              $selfenroll_access_start,$selfenroll_access_end,
                              $selfenroll_section,$now,$selfenroll_approval,
-                             $selfenroll_notifylist,$owner);
+                             $selfenroll_notifylist,$owner,$crstype,$lonhost,$handle);
     } elsif ($env{'form.phase'} eq 'login') {
         my $submit_text = &mt('Log in');
         $r->print('<h3>'.&mt('Log-in to LON-CAPA').'</h3>');
@@ -341,8 +349,7 @@ sub enrollment_limit_check {
 sub page_header {
     my ($r,$courseid,$js,$desc) = @_;
     my $start_page =
-        &Apache::loncommon::start_page('Self-enroll in a LON-CAPA course',$js,
-                                       {'no_inline_link'   => 1,});
+        &Apache::loncommon::start_page('Self-enroll in a LON-CAPA course',$js);
     $r->print($start_page);
     &Apache::lonhtmlcommon::clear_breadcrumbs();
     &Apache::createaccount::selfenroll_crumbs($r,$courseid,$desc);
@@ -358,17 +365,6 @@ sub page_footer {
     return;
 }
 
-sub validate_course_id {
-    my ($courseid) = @_;
-    my ($cdom,$cnum) = ($env{'form.courseid'} =~ /^($match_domain)_($match_courseid)$/);
-    if ($cdom ne '' && $cnum ne '') {
-        if (&Apache::lonnet::is_course($cdom,$cnum)) {
-            return ('ok',$courseid);
-        }
-    } 
-    return;
-}
-
 sub user_is_known {
     my $known = 0;
     if ($env{'user.name'} ne '' && $env{'user.name'} ne 'public'
@@ -404,7 +400,7 @@ sub has_role {
     my $output;
     if ($curr_role{'status'} eq 'active') {
           my $rolelink = &jump_to_role($curr_role{'role'});
-          $output = &mt('You already have an active student role (section: "[_1]") in this course.',$curr_role{'section'}).'<br>'.$rolelink;
+          $output = &mt('You already have an active student role (section: "[_1]") in this course.',$curr_role{'section'}).'<br />'.$rolelink;
     } elsif ($curr_role{'status'} eq 'future') {
         $output = &mt('You have a student role (section: "[_1]") in this course which will become active [_2].',$curr_role{'section'},$curr_role{'start'});
     }
@@ -414,7 +410,7 @@ sub has_role {
 sub process_self_enroll {
     my ($r,$cdom,$cnum,$selfenroll_types,$selfenroll_registered,
         $selfenroll_access_start,$selfenroll_access_end,$selfenroll_section,
-        $now,$selfenroll_approval,$selfenroll_notifylist,$owner) = @_;
+        $now,$selfenroll_approval,$selfenroll_notifylist,$owner,$crstype,$lonhost,$handle) = @_;
     my $udom = $env{'user.domain'};
     my $uname = $env{'user.name'};
     my $selfenroll = 0;
@@ -445,7 +441,8 @@ sub process_self_enroll {
             my ($registered,$instsec,$message) = &check_registered($cdom,$cnum);
             $usec = $instsec;
             if (!$registered) {
-                $r->print('<h3>'.&mt('Self-enrollment unavailable').'</h3>'.&mt('Self-enrollment is restricted to students officially registered for this course.').'<br />');
+                $r->print('<h3>'.&mt('Self-enrollment unavailable').'</h3>'.
+                          &mt('Self-enrollment is restricted to students officially registered for this course.').'<br />');
                 if ($message) {
                     $r->print($message);
                 } else {
@@ -457,7 +454,8 @@ sub process_self_enroll {
         if ($selfenroll_approval) {
             my $outcome = 
                 &store_selfenroll_request($udom,$uname,$usec,$cdom,$cnum,
-                                          $selfenroll_notifylist,$owner);
+                                          $selfenroll_notifylist,$owner,
+                                          $selfenroll_approval,$crstype,$lonhost,$handle);
             $r->print($outcome);
         } else {
             my $enrollresult = 
@@ -475,7 +473,7 @@ sub process_self_enroll {
                 }
                 &Apache::lonnet::standard_roleprivs(\%newrole,$role,$cdom,$spec,$cnum,
                                                     $area);
-                &Apache::lonnet::set_userprivs(\%userroles,\%newrole,%newgroups);
+                &Apache::lonnet::set_userprivs(\%userroles,\%newrole,\%newgroups);
                 $userroles{'user.role.'.$spec} = $selfenroll_access_start.'.'.$selfenroll_access_end;
                 &Apache::lonnet::appenv(\%userroles,[$role,'cm']);
                 $r->print('<h3>'.&mt('Enrollment process complete').'</h3>');
@@ -535,37 +533,118 @@ sub user_can_selfenroll {
 }
 
 sub store_selfenroll_request {
-    my ($udom,$uname,$usec,$cdom,$cnum,$selfenroll_notifylist,$owner) = @_;
+    my ($udom,$uname,$usec,$cdom,$cnum,$selfenroll_notifylist,$owner,
+        $selfenroll_approval,$crstype,$lonhost,$handle) = @_;
     my $namespace = 'selfenrollrequests';
     my $output;
     my $now = time;
     my %existing = 
         &Apache::lonnet::get($namespace,[$uname.':'.$udom],$cdom,$cnum);
     if ($existing{$uname.':'.$udom}) {
-        my ($timestamp,$sec) = split(/:/,$existing{$uname.':'.$udom});
-        $output = &mt('A self-enrollment request already exists for you for this course.').'<br />'.&mt('Your earlier request was submitted: [_1] and remains in a queue awaiting action by a Course Coordinator.',&Apache::lonlocal::locallocaltime($timestamp));
+        $output = &mt('A self-enrollment request already exists for you for this course.').'<br />'.
+                  &mt('Your earlier request is in a queue awaiting action by a Course Coordinator.').
+                  '<br /><br />'.&Apache::loncoursequeueadmin::queued_selfenrollment();
     } else {
         my %selfenroll = (
                             $uname.':'.$udom => $now.':'.$usec,
                          );
         my $putresult = &Apache::lonnet::put($namespace,\%selfenroll,$cdom,$cnum);
+        my $status = 'request';
+        if ($selfenroll_approval eq '2') {
+            $status = 'pending';
+        } 
         if ($putresult eq 'ok') {
-            $output = &mt('Your request for self-enrollment has been recorded.').'<br />'.
-                      &mt('A message will be sent to your LON-CAPA account when the course coordinator takes action on your request').'<br />';
-            my %emails = &Apache::loncommon::getemails($uname,$udom);
-            if (($emails{'permanentemail'} ne '') || ($emails{'notification'} ne '')) {
-                my $address = $emails{'permanentemail'};
-                if ($address eq '') {
-                    $address = $emails{'notification'};
-                }
-                $output.= &mt('An e-mail will also be sent to: [_1] when this occurs.',$address);
-            }
-            if ($selfenroll_notifylist) {
-                my $fullname = &Apache::loncommon::plainname($uname,$udom);
-                my %courseinfo = &Apache::lonnet::coursedescription($cdom.'_'.$cnum);
-                my $coursedesc = $courseinfo{'description'};
-                &send_notification($selfenroll_notifylist,$fullname,$cdom.
-                                   '_'.$cnum,$coursedesc,$now,'request',$owner);
+            my %userenroll = (
+                               $cdom.'_'.$cnum =>  {
+                                                      timestamp => $now,
+                                                      section   => $usec,
+                                                      status    => $status,
+                                                   });
+            my $token;
+            if ($status eq 'pending') {
+                $token = &Apache::lonnet::tmpput(\%selfenroll,$lonhost);
+                $userenroll{$cdom.'_'.$cnum}{'token'} = $token;
+                $userenroll{$cdom.'_'.$cnum}{'lonhost'} = $lonhost;
+                $userenroll{$cdom.'_'.$cnum}{'handle'} = $handle; 
+            } 
+            my $warning;
+            my $userresult = &Apache::lonnet::put($namespace,\%userenroll,$udom,$uname);
+            if ($userresult ne 'ok') {
+                $warning = &mt('An error occurred saving a personal record of your request.');
+            }
+            $output = &mt('Your request for self-enrollment has been recorded.').'<br />';
+            if ($status eq 'pending') {
+                my $coursetype = &Apache::lonuserutils::get_extended_type($cdom,$cnum,$crstype); 
+                my %postvalues = (
+                                   'username'   => $env{'user.name'},
+                                   'domain'     => $env{'user.domain'},
+                                   'course'     => $cdom.'_'.$cnum,
+                                   'coursetype' => $coursetype,
+                                   'token'      => $token,
+                                 );
+                my %domconfig = &Apache::lonnet::get_dom('configuration',['selfenrollment'],$cdom);
+
+                if (ref($domconfig{'selfenrollment'}) eq 'HASH') {
+                    my ($url,$buttontext,$code,@fields);
+                    if (ref($domconfig{'selfenrollment'}{'validation'}) eq 'HASH') {
+                        my %courseinfo = &Apache::lonnet::coursedescription($cdom.'_'.$cnum,{ 'one_time' => 1});
+                        $postvalues{'uniquecode'} = $courseinfo{'internal.uniquecode'};
+                        $postvalues{'description'} = $courseinfo{'description'};
+                        $url = $domconfig{'selfenrollment'}{'validation'}{'url'};
+                        if (ref($domconfig{'selfenrollment'}{'validation'}{'fields'}) eq 'ARRAY') {
+                            @fields = @{$domconfig{'selfenrollment'}{'validation'}{'fields'}};
+                        }
+                        $buttontext = $domconfig{'selfenrollment'}{'validation'}{'button'};
+
+                        $output .= $domconfig{'selfenrollment'}{'validation'}{'markup'};
+                        if (($url =~ m{^(https?\://|/)}) && (@fields > 0)) {
+                            $output .= '<form name="selfenrollvalidation" action="'.$url.'" method="post">'."\n";
+                            foreach my $field (@fields) {
+                                if ($postvalues{$field}) {
+                                    $output .= '<input type="hidden" name="'.$field.'" value="'.$postvalues{$field}.'" />'."\n";
+                                }
+                            }
+                            if ($buttontext eq '') {
+                                $buttontext = &mt('Complete my enrollment');
+                            }
+                            my $protocol = $Apache::lonnet::protocol{$lonhost};
+                            $protocol = 'http' if ($protocol ne 'https');
+                            my $enroller = $protocol.'://'.&Apache::lonnet::hostname($lonhost).'/cgi-bin/enrollqueued.pl';
+                            $output .= '<input type="hidden" name="enroller" value="'.$enroller.'" />'."\n".
+                                       '<input type="submit" name="validate" value="'.$buttontext.'" />'."\n".
+                                       '</form>'."\n";
+                        } else {
+                            $status = 'request';
+                        } 
+                    }
+                } else {
+                    $status = 'request';
+                }
+            }
+            if ($status eq 'request') {
+                $output .= &mt('A message will be sent to your LON-CAPA account when the course coordinator takes action on your request.').'<br />'.
+                           &mt('To access your LON-CAPA message, go to the Main Menu and click on "Send and Receive Messages".').'<br />';
+                my %emails = &Apache::loncommon::getemails($uname,$udom);
+                if (($emails{'permanentemail'} ne '') || ($emails{'notification'} ne '')) {
+                    my $address = $emails{'permanentemail'};
+                    if ($address eq '') {
+                        $address = $emails{'notification'};
+                    }
+                    $output.= &mt('An e-mail will also be sent to: [_1] when this occurs.',$address).'<br />';
+                }
+                if ($warning) { 
+                    $output .= '<span class="LC_warning">'.$warning.'</span><br />';
+                }
+                $output .= &Apache::loncoursequeueadmin::queued_selfenrollment();
+
+                if ($selfenroll_notifylist) {
+                    my $fullname = &Apache::loncommon::plainname($uname,$udom);
+                    my %courseinfo = &Apache::lonnet::coursedescription($cdom.'_'.$cnum);
+                    my $coursedesc = $courseinfo{'description'};
+                    &Apache::loncoursequeueadmin::send_selfserve_notification(
+                        $selfenroll_notifylist,$fullname,$cdom.'_'.$cnum,
+                        $coursedesc,$now,'selfenrollreq',$owner);
+                }
             }
         } else {
             $output = '<span class="LC_error">'.&mt('An error occurred when recording your request.').'</span>';
@@ -575,102 +654,6 @@ sub store_selfenroll_request {
     return $output;
 }
 
-sub send_notification {
-    my ($notifylist,$textstr,$cid,$coursedesc,$timestamp,$context,$sender,
-        $approvedlist,$rejectedlist) = @_;
-# FIXME locallocaltime needs to be able to take $sender_lh as an argument
-#       so this can be localized to the recipients date display format/time zone 
-    $timestamp =&Apache::lonlocal::locallocaltime($timestamp);
-    my $msgcc;
-    my ($rawsubj,@rawmsg,$subject,$message,$namelink);
-    $namelink = &Apache::loncommon::aboutmewrapper(
-                &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'}));
-    if ($context eq 'managers') {
-        $rawsubj = 'Self-enrollment requests processed';
-        push(@rawmsg,{
-                      mt => 'Enrollment requests in the following course: [_1] have been processed.',
-                      args => [$coursedesc],
-                     });
-    } elsif ($context eq 'enroller') {
-        $rawsubj = 'Enrollment request';
-        push(@rawmsg,{
-                      mt  => 'Your request for enrollment in the following course: [_1], requested on [_2], has been reviewed by a Course Coordinator.',
-                      args => [$coursedesc,$timestamp],
-                     });
-        if (ref($textstr) eq 'ARRAY') {
-            push(@rawmsg,@{$textstr});
-        }
-    } else {
-        $rawsubj = 'Self-enrollment request';
-        push(@rawmsg,{
-                      mt  => 'Enrollment in the following course: [_1] was requested by [_2] on [_3].',
-                      args => [$coursedesc,$textstr,$timestamp],
-                     },
-                     {
-                      mt =>'As Course Coordinator, use Main Menu -> Manage Couse Users -> "Enrollment Requests" to display a list of pending enrollment requests which you can either approve or reject.'
-                     });
-    }
-    my @to_notify = split(/,/,$notifylist);
-    my $numsent = 0;
-    my @recusers;
-    my @recudoms;
-    foreach my $cc (@to_notify) {
-        my ($ccname,$ccdom) = split(/:/,$cc);
-        if (!exists($msgcc->{$ccname.':'.$ccdom})) {
-            push(@recusers,$ccname);
-            push(@recudoms,$ccdom);
-            $msgcc->{$ccname.':'.$ccdom}='';
-            $numsent ++;
-        }
-    }
-    my %reciphash = (
-                     cc => $msgcc,
-    );
-    my ($uname,$udom);
-    if ($sender =~ /:/) {
-        ($uname,$udom) = split(/:/,$sender);
-    } else {
-        $uname = $sender;
-        my %courseinfo = &Apache::lonnet::coursedescription($cid);
-        $udom = $courseinfo{'num'};
-    }
-    my %sentmessage;
-    my $stamp = time;
-    my $msgcount = &Apache::lonmsg::get_uniq();
-    my $sender_lh = &Apache::loncommon::user_lang($uname,$udom,$cid);
-    $subject = &Apache::lonlocal::mt_user($sender_lh,$rawsubj);
-    $message = '';
-    foreach my $item (@rawmsg) {
-        if (ref($item) eq 'HASH') {
-            $message .= &Apache::lonlocal::mt_user($sender_lh,$item->{mt},@{$item->{args}})."\n";
-        }
-    }
-    &Apache::lonmsg::process_sent_mail($subject,'',$numsent,$stamp,$uname,$udom,$msgcount,$cid,$$,$message,\@recusers,\@recudoms);
-    my ($recipid,$recipstatus) =
-        &Apache::lonmsg::store_recipients($subject,$uname,$udom,\%reciphash);
-    foreach my $recip (sort(keys(%{$msgcc}))) {
-        my ($ccname,$ccdom) = split(/:/,$recip);
-        my $recip_lh = &Apache::loncommon::user_lang($ccname,$ccdom,$cid);
-        my $subject = &Apache::lonlocal::mt_user($sender_lh,$rawsubj);
-        my $message = '';
-        foreach my $item (@rawmsg) {
-            if (ref($item) eq 'HASH') {
-                $message .= &Apache::lonlocal::mt_user($sender_lh,$item->{mt},
-                                                       @{$item->{args}})."\n";
-            }
-        }
-        if ($context eq 'managers') {
-            if ($approvedlist) {
-                $message .= "\n\n".&Apache::lonlocal::mt_user($sender_lh,'Approved enrollments:')."\n".$approvedlist;
-            }
-            if ($rejectedlist) {
-                $message .= "\n\n".&Apache::lonlocal::mt_user($sender_lh,'Rejected enrollments:')."\n".$rejectedlist;
-            }
-        }
-        my $status = &Apache::lonmsg::user_normal_msg($ccname,$ccdom,$subject,$message,undef,undef,undef,1,\%sentmessage,undef,undef,undef,1,$recipid);
-    }
-}
-
 sub jump_to_role {
     my ($role) = @_;
     my $output = <<"END";