--- loncom/interface/loncoursequeueadmin.pm 2014/02/12 20:47:40 1.43 +++ loncom/interface/loncoursequeueadmin.pm 2016/06/19 00:19:31 1.54 @@ -1,7 +1,7 @@ # The LearningOnline Network # Utilities to administer domain course requests and course self-enroll requests # -# $Id: loncoursequeueadmin.pm,v 1.43 2014/02/12 20:47:40 raeburn Exp $ +# $Id: loncoursequeueadmin.pm,v 1.54 2016/06/19 00:19:31 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -90,6 +90,7 @@ use Apache::loncommon; use Apache::lonmsg; use Apache::lonlocal; use Apache::lonuserutils; +use LONCAPA::batchcreatecourse; use LONCAPA qw(:DEFAULT :match); sub send_selfserve_notification { @@ -522,6 +523,7 @@ sub build_queue_display { unofficial => 'Unofficial course', community => 'Community', textbook => 'Textbook course', + placement => 'Placement test', ); $output .= ''.&mt('Type').''. ''.&mt('Date requested').''. @@ -650,7 +652,7 @@ sub update_request_queue { $beneficiary = 'enroller'; $cid = $env{'request.course.id'}; $crstype = lc(&Apache::loncommon::course_type()); - $firsturl = &course_portal_url($cnum,$cdom); + $firsturl = &Apache::lonnet::course_portal_url($cnum,$cdom); %requesthash = &Apache::lonnet::dump($namespace,$cdom,$cnum); $access_start = $env{'course.'.$cid.'.internal.selfenroll_start_access'}; $access_end = $env{'course.'.$cid.'.internal.selfenroll_end_access'}; @@ -679,7 +681,7 @@ sub update_request_queue { } } my $domconfiguser = &Apache::lonnet::get_domainconfiguser($cdom); - $firsturl = &course_portal_url($domconfiguser,$cdom); + $firsturl = &Apache::lonnet::course_portal_url($domconfiguser,$cdom); $approvedmsg = [{ mt => 'Your request for Authoring Space has been approved.', }, @@ -704,7 +706,7 @@ sub update_request_queue { } } my $domconfiguser = &Apache::lonnet::get_domainconfiguser($cdom); - $firsturl = &course_portal_url($domconfiguser,$cdom); + $firsturl = &Apache::lonnet::course_portal_url($domconfiguser,$cdom); $approvedmsg = [{ mt => 'Your request for a LON-CAPA account has been approved.', }, @@ -876,7 +878,7 @@ sub update_request_queue { if (ref($curr{$uname}) eq 'HASH') { my ($username,$logtoken,$serverid,$encpass,$courseid,$id,$firstname, - $middlename,$lastname,$generation); + $middlename,$lastname,$generation,$inststatus); $curr{$uname}{'timestamp'} = $now; $curr{$uname}{'adjudicator'} = $env{'user.name'}.':'.$env{'user.domain'}; $courseid = $curr{$uname}{'courseid'}; @@ -885,6 +887,7 @@ sub update_request_queue { $middlename = $curr{$uname}{'middlename'}; $lastname = $curr{$uname}{'lastname'}; $generation = $curr{$uname}{'generation'}; + $inststatus = $curr{$uname}{'inststatus'}; my ($key,$caller)=split(/&/,$curr{$uname}{'tmpinfo'}); if ($caller eq 'createaccount') { @@ -901,6 +904,9 @@ sub update_request_queue { if ($uhome eq 'no_host') { push(@warn_approves,$uname); } else { + unless (($inststatus eq 'default') || ($inststatus eq '')) { + &Apache::lonnet::put('environment',{inststatus => $inststatus},$cdom,$uname); + } &send_selfserve_notification($uname.':'.$cdom, $approvedmsg,undef,undef,$now, $beneficiary,$sender); @@ -963,6 +969,9 @@ sub update_request_queue { } } } + if ($history{'details'}{'clonecrs'}) { + $customitems{'_LC_clonefrom'} = $history{'details'}{'clonedom'}.'_'.$history{'details'}{'clonecrs'}; + } my ($result,$postprocess) = &course_creation($cdom,$cnum,$context,$history{'details'},\$logmsg, \$newusermsg,\$addresult,\$enrollcount, \$response,\$keysmsg,\%domdefs,$longroles,\$code,\%customitems); @@ -972,7 +981,7 @@ sub update_request_queue { } else { $approvedmsg = $approvalmsg{'course'}; } - my $firsturl = &course_portal_url($cnum,$cdom); + my $firsturl = &Apache::lonnet::course_portal_url($cnum,$cdom); if (ref($approvedmsg) eq 'ARRAY') { if (ref($approvedmsg->[1]) eq 'HASH') { $approvedmsg->[1]->{'args'} = [$firsturl]; @@ -1306,7 +1315,7 @@ sub update_request_queue { my $syllabuslink = &Apache::loncommon::syllabuswrapper($showcourse,$cnum,$cdom); if ($codes{$cnum}) { - $syllabuslink .= &mt('Unique code: [_1]',$codes{$cnum}); + $syllabuslink .= ' '.&mt('Unique code: [_1]',$codes{$cnum}); } $output .= '
  • '.$syllabuslink.'
  • '; } @@ -1556,22 +1565,6 @@ sub update_request_queue { return $output; } -sub course_portal_url { - my ($cnum,$cdom) = @_; - my $chome = &Apache::lonnet::homeserver($cnum,$cdom); - my $hostname = &Apache::lonnet::hostname($chome); - my $protocol = $Apache::lonnet::protocol{$chome}; - $protocol = 'http' if ($protocol ne 'https'); - my %domdefaults = &Apache::lonnet::get_domain_defaults($cdom); - my $firsturl; - if ($domdefaults{'portal_def'}) { - $firsturl = $domdefaults{'portal_def'}; - } else { - $firsturl = $protocol.'://'.$hostname; - } - return $firsturl; -} - sub get_student_counts { my ($cdom,$cnum) = @_; my (%idx,%stucounts); @@ -1595,12 +1588,14 @@ sub course_creation { $keysmsg,$domdefs,$longroles,$coderef,$customhash) = @_; unless ((ref($details) eq 'HASH') && (ref($domdefs) eq 'HASH') && (ref($longroles) eq 'HASH')) { - return 'error: Invalid request'; + return ('error: Invalid request'); } my ($result,$ownername,$ownerdom); my $crstype = $details->{'crstype'}; my $coursedesc = $details->{'cdescr'}; - my %domconfig = &Apache::lonnet::get_dom('configuration',['requestauthor'],$dom); + my $accessstart = $details->{'accessstart'}; + my $accessend = $details->{'accessend'}; + my %domconfig = &Apache::lonnet::get_dom('configuration',['requestcourses'],$dom); if (ref($domconfig{'requestcourses'}) eq 'HASH') { if (ref($domconfig{'requestcourses'}{'uniquecode'}) eq 'HASH') { if ($domconfig{'requestcourses'}{'uniquecode'}{$crstype}) { @@ -1634,7 +1629,8 @@ sub course_creation { $code = $$coderef; } $postprocess = &Apache::lonnet::auto_crsreq_update($dom,$cnum,$crstype,$result,$ownername, - $ownerdom,$fullname,$coursedesc,$code,$customhash); + $ownerdom,$fullname,$coursedesc,$code, + $accessstart,$accessend,$customhash); } else { $result = 'error: '.$cid; } @@ -1663,6 +1659,8 @@ sub build_batchcreatehash { $batchhash{'authparam'} = $domdefs->{'auth_arg_def'}; if ($details->{'crstype'} eq 'community') { $batchhash{'crstype'} = 'Community'; + } elsif ($details->{'crstype'} eq 'placement') { + $batchhash{'crstype'} = 'Placement'; } else { if ($details->{'crstype'} eq 'textbook') { if ($details->{'clonecrs'} && $details->{'clonedom'}) { @@ -1713,7 +1711,7 @@ sub build_batchcreatehash { } sub can_clone_course { - my ($uname,$udom,$clonecrs,$clonedom,$crstype) = @_; + my ($uname,$udom,$clonecrs,$clonedom,$crstype,$dom,$instcode) = @_; my $canclone; my $ccrole = 'cc'; if ($crstype eq 'community') { @@ -1724,19 +1722,70 @@ sub can_clone_course { if (exists($roleshash{$clonecrs.':'.$clonedom.':'.$ccrole})) { $canclone = 1; } else { - my %courseenv = &Apache::lonnet::userenvironment($clonedom,$clonecrs,('cloners')); + my %courseenv = &Apache::lonnet::userenvironment($clonedom,$clonecrs, + ('cloners','internal.coursecode')); my $cloners = $courseenv{'cloners'}; + my $clonefromcode = $courseenv{'internal.coursecode'}; if ($cloners ne '') { my @cloneable = split(',',$cloners); if (grep(/^\*$/,@cloneable)) { $canclone = 1; - } - if (grep(/^\*:\Q$udom\E$/,@cloneable)) { + } elsif (grep(/^\*:\Q$udom\E$/,@cloneable)) { $canclone = 1; - } - if (grep(/^\Q$uname\E:\Q$udom\E$/,@cloneable)) { + } elsif (grep(/^\Q$uname\E:\Q$udom\E$/,@cloneable)) { $canclone = 1; } + unless ($canclone) { + if (($clonefromcode) && ($instcode) && ($clonedom eq $dom)) { + my (%gotdomdefaults,%gotcodedefaults); + foreach my $cloner (@cloneable) { + if (($cloner ne '*') && ($cloner !~ /^\*\:$match_domain$/) && + ($cloner !~ /^$match_username\:$match_domain$/) && ($cloner ne '')) { + if ($cloner =~ /\=/) { + my (%codedefaults,@code_order); + if (ref($gotcodedefaults{$clonedom}) eq 'HASH') { + if (ref($gotcodedefaults{$clonedom}{'defaults'}) eq 'HASH') { + %codedefaults = %{$gotcodedefaults{$clonedom}{'defaults'}}; + } + if (ref($gotcodedefaults{$clonedom}{'order'}) eq 'ARRAY') { + @code_order = @{$gotcodedefaults{$dom}{'order'}}; + } + } else { + &Apache::lonnet::auto_instcode_defaults($clonedom, + \%codedefaults, + \@code_order); + $gotcodedefaults{$clonedom}{'defaults'} = \%codedefaults; + $gotcodedefaults{$clonedom}{'order'} = \@code_order; + } + if (@code_order > 0) { + if (&Apache::lonnet::check_instcode_cloning(\%codedefaults,\@code_order, + $cloner,$clonefromcode,$instcode)) { + $canclone = 1; + last; + } + } + } + } + } + } + } + } else { + my %domdefs = &Apache::lonnet::get_domain_defaults($clonedom); + if ($domdefs{'canclone'}) { + unless ($domdefs{'canclone'} eq 'none') { + if ($domdefs{'canclone'} eq 'domain') { + if ($udom eq $clonedom) { + $canclone = 1; + } + } elsif (($clonefromcode) && ($instcode) && + ($clonedom eq $dom)) { + if (&Apache::lonnet::default_instcode_cloning($clonedom,$domdefs{'canclone'}, + $clonefromcode,$instcode)) { + $canclone = 1; + } + } + } + } } unless ($canclone) { if (&Apache::lonnet::is_course_owner($clonedom,$clonecrs,$uname,$udom)) { @@ -2018,6 +2067,9 @@ sub process_official_reqs { } } } + if ($history{'details'}{'clonecrs'}) { + $customitems{'_LC_clonefrom'} = $history{'details'}{'clonedom'}.'_'.$history{'details'}{'clonecrs'}; + } my ($result,$postprocess) = &course_creation($dom,$cnum,'domain',$history{'details'},\$logmsg,\$newusermsg,\$addresult, \$enrollcount,\$response,\$keysmsg,\%domdefs,\%longroles,\$code,\%customitems); @@ -2027,7 +2079,7 @@ sub process_official_reqs { my $cid = $dom.'_'.$cnum; push(@{$newcids{$instcode}},$cid); if ($dcname && $dcdom) { - my $firsturl = &course_portal_url($cnum,$dom); + my $firsturl = &Apache::lonnet::course_portal_url($cnum,$dom); my $beneficiary = 'pendingrequestor'; my $now = time; my $owner = $ownername.':'.$ownerdom; @@ -2054,6 +2106,11 @@ sub process_official_reqs { } } } + if (ref($postprocess->{'createdactions'}) eq 'HASH') { + if (ref($postprocess->{'createdactions'}{'environment'}) eq 'HASH') { + &postprocess_crsenv($dom,$cnum,$postprocess->{'createdactions'}{'environment'}); + } + } } &send_selfserve_notification($owner,$approvedmsg, $cid,$cdescr,$now, @@ -2125,6 +2182,68 @@ sub process_official_reqs { return $output; } +sub postprocess_crsenv { + my ($dom,$cnum,$postprocessenv) = @_; + if (ref($postprocessenv) eq 'HASH') { + my $cid = $dom.'_'.$cnum; + my %settablecrsenv = ( + 'internal.selfenroll_types' => 1, + 'internal.selfenroll_registered' => 1, + 'internal.selfenroll_section' => 1, + 'internal.selfenroll_start_access' => 1, + 'internal.selfenroll_end_access' => 1, + 'internal.selfenroll_limit' => 1, + 'internal.selfenroll_cap' => 1, + 'internal.selfenroll_approval' => 1, + 'internal.selfenroll_notifylist' => 1, + ); + my %needcrsidput = ( + 'internal.selfenroll_types' => 1, + 'internal.selfenroll_start_date' => 1, + 'internal. selfenroll_end_date' => 1, + ); + my (@needupdate,%newcrsenv); + foreach my $key (keys(%{$postprocessenv})) { + if ($settablecrsenv{$key}) { + $newcrsenv{$key} = $postprocessenv->{$key}; + if ($needcrsidput{$key}) { + push(@needupdate,$key); + } + } + if (keys(%newcrsenv)) { + my $putresult = &Apache::lonnet::put('environment',\%newcrsenv,$dom,$cnum); + if ($putresult eq 'ok') { + if (@needupdate) { + my %crsinfo = + &Apache::lonnet::courseiddump($dom,'.',1,'.','.',$cnum,undef,undef,'.'); + if (ref($crsinfo{$cid}) eq 'HASH') { + foreach my $key (@needupdate) { + $crsinfo{$cid}{$key} = $newcrsenv{$key}; + } + my $chome = &Apache::lonnet::homeserver($cnum,$dom); + &Apache::lonnet::courseidput($dom,\%crsinfo,$chome,'notime'); + } + } + } + } + } + } + return; +} + + +sub requestcourses_validation_types { + my @items = ('url','fields','button','markup'); + my %names = &Apache::lonlocal::texthash ( + url => 'Web address of validation server/script', + fields => 'Form fields to send to validator', + button => 'Text for validation button', + markup => 'Validation description (HTML)', + ); + my @fields = ('owner','course','coursetype','description'); + return (\@items,\%names,\@fields); +} + sub is_active_author { if ($env{'user.role.au./'.$env{'user.domain'}.'/'} =~ /^(\d*)\.(\d*)$/) { if ((!$1 || $1 < time) &&