# The LearningOnline Network # Allow users to self-enroll in a course # # $Id: selfenroll.pm,v 1.3 2008/05/14 20:06:51 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # # package Apache::selfenroll; use strict; use Apache::Constants qw(:common); use Apache::lonnet; use Apache::loncommon; use Apache::lonlocal; use LONCAPA qw(:DEFAULT :match); sub handler { my $r = shift; &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; if ($r->header_only) { return OK; } my $handle = &Apache::lonnet::check_for_valid_session($r); my $lonidsdir=$r->dir_config('lonIDsDir'); if ($handle ne '') { &Apache::lonnet::transfer_profile_to_env($lonidsdir,$handle); } &Apache::lonacc::get_posted_cgi($r); &Apache::lonlocal::get_language_handle($r); &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['cid']); my ($coursechk,$cid) = &validate_course_id($env{'form.cid'}); my $start_page = &Apache::loncommon::start_page('Self-enroll in a LON-CAPA course','', {'no_inline_link' => 1,}); $r->print($start_page); &Apache::lonhtmlcommon::clear_breadcrumbs(); &Apache::lonhtmlcommon::add_breadcrumb ({href=>"/adm/selfenroll?cid=$cid", text=>"Self-enroll"}); $r->print(&Apache::lonhtmlcommon::breadcrumbs('Self-enroll in course')); if ($coursechk ne 'ok') { $r->print(&mt('Invalid domain or course number')); $r->print(&Apache::loncommon::end_page()); return OK; } my ($cdom,$cnum,$canenroll,$selfenroll_types,$selfenroll_registered, @cancreate,$knownuser,$selfenroll_access_start,$selfenroll_access_end, $selfenroll_section,%curr_role,%coursehash); my $now = time; %coursehash = &Apache::lonnet::coursedescription($cid); $cdom = $coursehash{'domain'}; $cnum = $coursehash{'num'}; $selfenroll_types = $coursehash{'internal.selfenroll_types'}; $selfenroll_registered = $coursehash{'internal.selfenroll_registered'}; $selfenroll_section = $coursehash{'internal.selfenroll_section'}; $selfenroll_access_start = $coursehash{'internal.selfenroll_start_access'}; $selfenroll_access_end = $coursehash{'internal.selfenroll_end_access'}; if ($selfenroll_types ne '') { my $start = $coursehash{'internal.selfenroll_start_date'}; my $end = $coursehash{'internal.selfenroll_end_date'}; if (($start > 0 && $start < $now) && ($end > 0 && $end > $now)) { $canenroll = 1; } } if (!$canenroll) { $r->print(&mt('Self-enrollment is not currently available for this course.').'

'); } $knownuser = &user_is_known(); if ($knownuser) { foreach my $key (keys(%env)) { if ($key =~ m-^user\.role\.st\./$cdom/$cnum/?(\w*)$-) { my $sec = $1; if ($sec eq '') { $sec = &mt('none'); } my ($start,$end) = split(/\./,$env{$key}); my $status = 'active'; if (($end) && ($end<=$now)) { $status = 'previous'; } if (($start) && ($now<$start)) { $status = 'future'; } if ($status eq 'active' || $status eq 'future') { $curr_role{'status'} = $status; $curr_role{'section'} = $sec; $curr_role{'start'} = &Apache::lonlocal::locallocaltime($start); $curr_role{'role'} = 'st./'.$cdom.'/'.$cnum; if ($sec ne '') { $curr_role{'role'} .= '/'.$sec; } } } } } if (!$canenroll) { if (keys(%curr_role)) { $r->print(&has_role(%curr_role)); } $r->print(&Apache::loncommon::end_page()); return OK; } @cancreate = &can_create($cdom); my ($login_path,$firsturl,$create_path,$sso_url,$missing_formitem); $login_path = '/adm/login'; $firsturl= '/adm/selfenroll?cid='.$cid; $create_path = '/adm/createaccount'; $sso_url = $r->dir_config('lonSSOReloginServer'); if ($sso_url eq '') { $sso_url = $login_path; } my $missing_formitem = &mt('The link to the requested page could not be followed.')."\\n".&mt('The placeholder for the courseID is absent.'); if ($knownuser) { if (keys(%curr_role)) { $r->print(&has_role(%curr_role)); return OK; } &process_self_enroll($r,$cdom,$cnum,$selfenroll_types,$selfenroll_registered, $selfenroll_access_start,$selfenroll_access_end, $selfenroll_section,$now); } elsif (@cancreate > 0) { $r->print(< function setPath(formaction,item,arg) { document.forms.logmein.action = formaction; var itemid = getIndexByName("setting"); if (itemid > -1) { document.logmein.elements[itemid].name = item; document.logmein.elements[itemid].value = arg; document.logmein.submit(); } else { alert("$missing_formitem"); } return; } function getIndexByName(item) { for (var i=0;i END $r->print(&mt('You need to be logged into LON-CAPA to self-enroll in a course.').''); } else { $r->print(''); my ($enrolltypes,$longtypes,$alldoms) = &get_selfenroll_filters($selfenroll_types,$cdom); $r->print(&print_selfenroll_types($longtypes,$cdom)); } } else { $r->print(&mt('You must [_1]log-in[_2] to LON-CAPA with an existing account to be able to enroll in this course, as account creation is not permitted when self-enrolling.','','')); if ($selfenroll_types ne '*') { my ($enrolltypes,$longtypes,$alldoms) = &get_selfenroll_filters($selfenroll_types); $r->print('

'.&print_selfenroll_types($longtypes)); } } $r->print('
'."\n". ''."\n". '
'."\n". &Apache::loncommon::end_page()); return OK; } sub validate_course_id { my ($cid) = @_; my ($cdom,$cnum) = ($env{'form.cid'} =~ /^($match_domain)_($match_courseid)$/); if ($cdom ne '' && $cnum ne '') { if (&Apache::lonnet::is_course($cdom,$cnum)) { return ('ok',$cid); } } return; } sub user_is_known { my $known = 0; if ($env{'user.name'} ne '' && $env{'user.name'} ne 'public' && $env{'user.domain'} ne '' && $env{'user.domain'} ne 'public') { $known = 1; } return $known; } sub can_create { my ($cdom) = @_; my @cancreate; my %domconfig = &Apache::lonnet::get_dom('configuration',['usercreation'],$cdom); if (ref($domconfig{'usercreation'}) eq 'HASH') { if (ref($domconfig{'usercreation'}{'cancreate'}) eq 'HASH') { if ($domconfig{'usercreation'}{'cancreate'}{'selfcreate'} ne 'none') { if (ref($domconfig{'usercreation'}{'cancreate'}{'selfcreate'}) eq 'ARRAY') { @cancreate = @{$domconfig{'usercreation'}{'cancreate'}{'selfcreate'}}; } else { if (($domconfig{'usercreation'}{'cancreate'}{'selfcreate'} ne 'none') && ($domconfig{'usercreation'}{'cancreate'}{'selfcreate'} ne '')) { @cancreate = ($domconfig{'usercreation'}{'cancreate'}{'selfcreate'}); } } } } } return @cancreate; } sub has_role { my (%curr_role) = @_; my $output; if ($curr_role{'status'} eq 'active') { my $rolelink = &jump_to_role($curr_role{'role'}); $output = &mt('You currently have an active role (section: "[_1]") in this course.',$curr_role{'section'}).' '.$rolelink; } elsif ($curr_role{'status'} eq 'future') { $output = &mt('You have a role (section: "[_1]") in this course which will become active [_2].',$curr_role{'section'},$curr_role{'start'}); } return $output; } sub process_self_enroll { my ($r,$cdom,$cnum,$selfenroll_types,$selfenroll_registered, $selfenroll_access_start,$selfenroll_access_end,$selfenroll_section,$now) = @_; my $udom = $env{'user.domain'}; my $uname = $env{'user.name'}; my @info = ['inststatus']; my %userhash = &Apache::lonnet::userenvironment($udom,$uname,@info); my ($enrolltypes,$longtypes,$alldoms) = &get_selfenroll_filters($selfenroll_types,$udom); my @inststatuses = &unescape(split(/:/,$userhash{'inststatus'})); if (@inststatuses == 0) { push(@inststatuses,'other'); } my $selfenroll = 0; if ($alldoms) { $selfenroll = 1; } elsif (ref($enrolltypes) eq 'HASH') { if (ref($enrolltypes->{$udom}) eq 'ARRAY') { if (grep(/^any$/,@{$enrolltypes->{$udom}})) { $selfenroll = 1; } else { foreach my $type (@inststatuses) { if (grep(/^\Q$type\E$/,@{$enrolltypes->{$udom}})) { $selfenroll = 1; last; } } } } } if ($selfenroll) { my $usec = $selfenroll_section; if ($selfenroll_section eq 'none') { $usec = ''; } if ($selfenroll_registered) { my ($registered,$instsec,$message) = &check_registered($cdom,$cnum); $usec = $instsec; if (!$registered) { $r->print(&mt('Self-enrollment is restricted to officially registered students.').'
'); if ($message) { $r->print($message); } else { $r->print(&mt('As you are not currently registered for this course, self-enrollment is unavailable.')); } return; } } my $enrollresult = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef, undef,undef,$usec,$selfenroll_access_end,$selfenroll_access_start, 'manual',undef,$cdom.'_'.$cnum,$selfenroll); if ($enrollresult eq 'ok') { my (%userroles,%newrole,%newgroups); my $role = 'st'; my $area = '/'.$cdom.'/'.$cnum; my $spec = $role.'.'.$area; if ($usec ne '') { $spec .= '/'.$usec; $area .= '/'.$usec; } &Apache::lonnet::standard_roleprivs(\%newrole,$role,$cdom,$spec,$cnum, $area); &Apache::lonnet::set_userprivs(\%userroles,\%newrole,%newgroups); $userroles{'user.role.'.$spec} = $selfenroll_access_start.'.'.$selfenroll_access_end; &Apache::lonnet::appenv(\%userroles,[$role]); if ($selfenroll_access_end && $selfenroll_access_end <= $now) { $r->print(&mt('The end date for access to this course for users who self-enroll has passed.').'
'.&mt('Consequently, although a new role was created for you in the course, it is an inactive role which does not provide access to the course.')); } else { $r->print(&mt('Self-enrollment in this course was successful.').'
'); my $showstart = &Apache::lonlocal::locallocaltime($selfenroll_access_start); my $showend = &Apache::lonlocal::locallocaltime($selfenroll_access_end); if ($selfenroll_access_start && $selfenroll_access_start >$now) { $r->print(&mt('The start date for access to this course for users who self-enroll has yet to be reached.').'
'.&mt('Consequently, although a new role was created for you in the course, you will not be able to select this role until [_1].',$showstart)); } else { my $newrole = 'st./'.$cdom.'/'.$cnum; if ($usec ne '') { $newrole .= '/'.$usec; } my $rolelink = &jump_to_role($newrole); $r->print(&mt('Your new role is available immediately, and will provide access to the course until [_1].',$showend).'

'."\n". $rolelink); } } } else { $r->print(&mt('Self-enrollment in this course failed.')); if ($enrollresult ne '') { $r->print(''.$enrollresult.''); } } } else { $r->print(&mt('You are not permitted to enroll yourself in this course.').'
'); $r->print(&print_selfenroll_types($longtypes)); } return; } sub jump_to_role { my ($role) = @_; my $output = <<"END"; END $output .= ''."\n". &mt('Enter course now').''."\n". '
'."\n". ''."\n". ''."\n". '
'; return $output; } sub get_selfenroll_filters { my ($selfenroll_types,$domain) = @_; my (%enrolltypes,%longtypes,$alldoms); my @selfenrolldoms = split(/;/,$selfenroll_types); foreach my $item (@selfenrolldoms) { my ($selfdom,$type_str) = split(/:/,$item); if ($selfdom eq '*') { $alldoms = 1; last; } if ($domain ne '') { next if ($selfdom ne $domain); } if ($selfdom =~ /^$match_domain$/) { if (&Apache::lonnet::domain($selfdom) ne '') { my @types = split(/,/,$type_str); my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($selfdom); if (ref($usertypes) eq 'HASH') { $usertypes->{'any'} = &mt('any'); $usertypes->{'other'} = &mt('other'); @{$enrolltypes{$selfdom}} = @types; @{$longtypes{$selfdom}} = map {$usertypes->{$_}} @types; } } } } return (\%enrolltypes,\%longtypes,$alldoms); } sub print_selfenroll_types { my ($longtypes,$domain) = @_; my $output; if (ref($longtypes) eq 'HASH') { if (keys(%{$longtypes}) > 0) { if ($domain ne '') { if (ref($longtypes->{$domain}) eq 'ARRAY') { if (grep(/^any$/,@{$longtypes->{$domain}})) { $output = &mt('Self-enrollment in this course is only available to users in domain "[_1]".',$domain); } else { my $status_str = join(', ',@{$longtypes->{$domain}}); $output = &mt('Self-enrollment in this course is only available to users in domain "[_1]" who have the following status: "[_2]".',$domain,$status_str); } } } else { $output = &mt('Self-enrollment in this course is only available to users in the following domains (with the following status): ').''; } } else { $output = &mt('Self-enrollment is not currently available in this course'); } } return $output; } sub check_registered { my ($cdom,$cnum) = @_; my ($registered,$instsec,$message); my %settings = &Apache::lonnet::get('environment',['internal.coursecode', 'internal.sectionnums', 'internal.crosslistings'],$cdom,$cnum); my (@allcourses,%LC_code,%affiliates,%reply); &Apache::loncommon::get_institutional_codes(\%settings,\@allcourses,\%LC_code); if (@allcourses > 0) { @{$affiliates{$cnum}} = @allcourses; my $outcome = &Apache::lonnet::fetch_enrollment_query('updatenow',\%affiliates,\%reply,$cdom,$cnum); if ($outcome eq 'ok') { if ($reply{$cnum} > 0) { foreach my $class (@allcourses) { my %enrolled; my $dir = $Apache::lonnet::perlvar{'lonDaemons'}; my %place = &LONCAPA::Enrollment::place_hash(); &LONCAPA::Enrollment::parse_classlist($dir,$cdom,$cnum,$class, \%place,$LC_code{$class},\%enrolled); if (defined($enrolled{$env{'user.name'}})) { $registered = 1; $instsec = $LC_code{$class}; last; } } } else { $message = &mt('Your registration status could not be verified.'); } } else { $message = &mt('Your registration status could not determined, because a problem occurred retrieving data.'); } } else { $message = &mt('As no institutional course sections are currently associated with this course, your registration status is undetermined.'); } return ($registered,$instsec,$message); } 1;