--- loncom/interface/lonrequestcourse.pm 2023/03/11 04:54:24 1.95.2.7.2.3 +++ loncom/interface/lonrequestcourse.pm 2021/11/24 04:25:02 1.113 @@ -1,7 +1,7 @@ # The LearningOnline Network # Request a course # -# $Id: lonrequestcourse.pm,v 1.95.2.7.2.3 2023/03/11 04:54:24 raeburn Exp $ +# $Id: lonrequestcourse.pm,v 1.113 2021/11/24 04:25:02 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -163,6 +163,23 @@ sub handler { } if ($canreq) { + if (($env{'form.crstype'} eq 'lti') && ($env{'request.lti.login'}) && + ($env{'form.lti.reqrole'} eq 'cc') && ($env{'form.lti.reqcrs'}) && + ($env{'form.lti.sourcecrs'} ne '')) { + if ($action eq 'process') { + if ($can_request{'lti'}) { + my %domconfig = &Apache::lonnet::get_dom('configuration',['requestcourses'],$dom); + &process_textbook_request($r,$dom,$action,\%domdefs,\%domconfig,\%can_request,'lti'); + } else { + $r->print(&header('Course Request','','','',{ 'only_body' => 1}). + '
'. + '

'.&mt('You do not have privileges to request creation of LTI courses.').'

'. + '
'. + &Apache::loncommon::end_page()); + } + } + return OK; + } if (($env{'form.crstype'} eq 'textbook') || (scalar(keys(%can_request)) == 1) && ($can_request{'textbook'})) { my %domconfig = &Apache::lonnet::get_dom('configuration',['requestcourses'],$dom); @@ -200,7 +217,8 @@ sub handler { } } else { if ($can_request{'textbook'}) { - &print_textbook_form($r,$dom,\@incdoms,\%domdefs,$domconfig{'requestcourses'},\%can_request); + &print_textbook_form($r,$dom,\@incdoms,\%domdefs,$domconfig{'requestcourses'}, + \%can_request,'textbook'); } else { &textbook_request_disabled($r,$dom,$action,\%can_request); } @@ -319,6 +337,8 @@ sub handler { $jscript = &Apache::lonhtmlcommon::set_form_elements($elementsref,\%stored); if ($state eq 'courseinfo') { $jscript .= &cloning_javascript(); + } elsif ($state eq 'process') { + $jscript .= &processing_javascript(); } } } @@ -430,6 +450,17 @@ function setCloneDisplay(courseForm) { END } +sub processing_javascript { + return <<"END"; +function hideProcessing() { + if (document.getElementById('processing')) { + document.getElementById('processing').style.display="none"; + } +} + +END +} + sub get_breadcrumbs { my ($dom,$action,$state,$states,$trail) = @_; my ($crumb,$newinstcode,$codechk,$checkedcode,$numtitles,$description); @@ -708,6 +739,9 @@ sub onload_action { if ($state eq 'courseinfo') { $loaditems{'onload'} .= 'javascript:setCloneDisplay(document.requestcrs);'; } + if ($state eq 'process') { + $loaditems{'onload'} .= 'javascript:hideProcessing();'; + } } return \%loaditems; } @@ -753,6 +787,7 @@ function check_can_request(crschoice,act var unofficial = ''; var community = ''; var textbook = ''; + var placement = ''; END if (ref($can_request) eq 'HASH') { foreach my $item (keys(%{$can_request})) { @@ -766,6 +801,7 @@ END unofficial => 'You are not permitted to request creation of an unofficial course in this domain.', community => 'You are not permitted to request creation of a community in this domain.', textbook => 'You are not permitted to request creation of a textbook course in this domain', + placement => 'You are not permitted to request creation of a placement test in this domain', all => 'You must choose a specific course type when making a new course request.', allt => '"All types" is not allowed.', ); @@ -795,9 +831,16 @@ END return false; } } else { - if (actionchoice == 'new') { - alert('$js_lt{'all'}'+'\\n'+'$js_lt{'allt'}'); - return false; + if (crschoice == 'placement') { + if (placement != 1) { + alert("$js_lt{'placement'}"); + return false; + } + } else { + if (actionchoice == 'new') { + alert('$js_lt{'all'}'+'\\n'+'$js_lt{'allt'}'); + return false; + } } } } @@ -808,7 +851,7 @@ END END my ($pagetitle,$pageinfo,$domaintitle,$earlyout); if (ref($can_request) eq 'HASH') { - if (($can_request->{'official'}) || ($can_request->{'unofficial'}) || $can_request->{'textbook'}) { + if (($can_request->{'official'}) || ($can_request->{'unofficial'}) || ($can_request->{'textbook'}) || ($can_request->{'placement'})) { if ($can_request->{'community'}) { $pagetitle = 'Course/Community Requests'; $pageinfo = &mt('Request creation of a new course or community, or review your pending requests.'); @@ -985,6 +1028,8 @@ END $title = &mt('Pending requests for unofficial courses'); } elsif ($env{'form.crstype'} eq 'textbook') { $title = &mt('Pending requests for textbook courses'); + } elsif ($env{'form.crstype'} eq 'textbook') { + $title = &mt('Pending requests for placement tests'); } else { $title = &mt('Pending course/community requests'); } @@ -2086,7 +2131,8 @@ sub print_personnel_menu { official => 'Requestor is automatically assigned Course Coordinator role.', ); $lt{'unofficial'} = $lt{'official'}; - $lt{'textbook'} = $lt{'textbook'}; + $lt{'textbook'} = $lt{'official'}; + $lt{'placement'} = $lt{'official'}; $output .= &Apache::lonhtmlcommon::row_headline(). '

'.&Apache::loncommon::help_open_topic('Course_Request_Personnel').' '.$lt{$crstype}.' '.&mt('Include other personnel?').'

'; } @@ -2102,14 +2148,15 @@ sub print_personnel_menu { } } } - for (my $i=0; $i<$persontotal; $i++) { + my ($trusted,$untrusted) = &Apache::lonnet::trusted_domains('enroll',$dom); + for (my $i=0; $i<$persontotal; $i++) { my @linkargs = map { 'person_'.$i.'_'.$_ } (@items); my $linkargstr = join("','",@linkargs); my $uname_form = ''; my $onchange = 'javascript:fix_domain('."'$formname','person_".$i."_dom',". "'person_".$i."_hidedom','person_".$i."_uname'".');'; my $udom_form = &Apache::loncommon::select_dom_form($dom,'person_'.$i.'_dom','', - 1,$onchange). + 1,$onchange,undef,$trusted,$untrusted). ''; my %form_elems; foreach my $item (@items) { @@ -2514,7 +2561,7 @@ sub print_request_logs { if (ref($domconfig{'requestcourses'}) eq 'HASH') { if (ref($domconfig{'requestcourses'}{'uniquecode'}) eq 'HASH') { if ($curr{'crstype'} eq 'any') { - my @types = qw(official unofficial community textbook); + my @types = qw(official unofficial community textbook placement); foreach my $type (@types) { if ($domconfig{'requestcourses'}{'uniquecode'}{$type}) { $showuniquecode = 1; @@ -2682,7 +2729,7 @@ sub reqstatus_names { rejected => 'Request rejected', cancelled => 'Request cancelled', ); - if (($crstype eq 'official') || ($crstype eq 'unofficial') || ($crstype eq 'textbook')) { + if (($crstype eq 'official') || ($crstype eq 'unofficial') || ($crstype eq 'textbook') || ($crstype eq 'placement')) { $statusnames{'created'} = &mt('Course created'); } elsif ($crstype eq 'community') { $statusnames{'created'} = &mt('Community created'); @@ -3095,6 +3142,7 @@ sub courseinfo_form { &js_escape(\%js_lt); $js_lt{'unofficial'} = $js_lt{'official'}; $js_lt{'textbook'} = $js_lt{'official'}; + $js_lt{'placement'} = $js_lt{'official'}; my $js_validate = <<"ENDJS"; -ENDCLOSE - my %prog_state = &Apache::lonhtmlcommon::Create_PrgWin($r,undef,$preamble); - &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,&mt('Processing ...')); + $r->print('
'."\n". + &mt('Your request is being processed; this page will update when processing is complete.'). + '
'); $r->rflush(); if (ref($details) eq 'HASH') { if ($details->{'clonecrs'}) { @@ -3859,9 +3892,6 @@ ENDCLOSE 'autocreate',$details,\$logmsg,$clonemsg,\$newusermsg, \$addresult,\$enrollcount,\$response,\$keysmsg,\%domdefs, \%longroles,\$code,\%customitems); - &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,&mt('Finished!')); - &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state); - $r->print($closure); if (ref($postprocess) eq 'HASH') { $customized = $postprocess->{'createdcustomized'}; } @@ -4417,7 +4447,7 @@ sub check_autolimit { if (($crstype eq 'community') && (exists($crsroles{$cnum.':'.$cdom.':co'}))) { $count ++; - } elsif ((($crstype eq 'official') || ($crstype eq 'unofficial') || ($crstype eq 'textbook')) && + } elsif ((($crstype eq 'official') || ($crstype eq 'unofficial') || ($crstype eq 'textbook') || ($crstype eq 'placement')) && (exists($crsroles{$cnum.':'.$cdom.':cc'}))) { $count ++; } @@ -4620,9 +4650,11 @@ sub generate_date_items { } sub print_textbook_form { - my ($r,$dom,$incdoms,$domdefs,$settings,$can_request) = @_; + my ($r,$dom,$incdoms,$domdefs,$settings,$can_request,$crstype,$formhash) = @_; my (%prefab,%ordered,%numprefab); - my $crstype = 'textbook'; + if ($crstype eq '') { + $crstype = 'textbook'; + } # # Retrieve list of prefabricated courses (textbook courses and templates) cloneable by user # @@ -4682,7 +4714,7 @@ sub print_textbook_form { owner => $courseinfo{'internal.courseowner'}, releaserequired => $courseinfo{'internal.releaserequired'}, type => $courseinfo{'type'}, - }; + }; } } @@ -4739,31 +4771,37 @@ sub print_textbook_form { my $jscript = &textbook_request_javascript(\%numprefab,$numcurrent,$numdomcourses,$customvalidationjs); $jscript .= $customjs; - my %loaditems; + my (%loaditems,$args); $loaditems{'onload'} = 'javascript:uncheckAllRadio();'.$customonload; - $r->print(&header('Course Request',$jscript,\%loaditems)); + if ($crstype eq 'lti') { + $args = { 'only_body' => 1}; + } + $r->print(&header('Course Request',$jscript,\%loaditems,undef,$args)); if (ref($can_request) eq 'HASH') { - unless ((scalar(keys(%{$can_request})) == 1) && ($can_request->{'textbook'})) { + unless (((scalar(keys(%{$can_request})) == 1) && ($can_request->{'textbook'})) || + ($crstype eq 'lti')) { &Apache::lonhtmlcommon::add_breadcrumb( { href => '/adm/requestcourse', text => 'Pick action', }); } } - &Apache::lonhtmlcommon::add_breadcrumb({text=>'Course Request'}); - $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course Requests','Course_Requests')); + unless ($crstype eq 'lti') { + &Apache::lonhtmlcommon::add_breadcrumb({text=>'Course Request'}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course Requests','Course_Requests')); - &startContentScreen($r,'textbookrequests'); + &startContentScreen($r,'textbookrequests'); # # Show domain selector form, if required. # - if (@{$incdoms} > 1) { - my $onchange = 'this.form.submit()'; - $r->print('
'. - '
'.&mt('Domain').''. - &Apache::loncommon::select_dom_form($dom,'showdom','',1,$onchange,$incdoms). - '
'); + if (@{$incdoms} > 1) { + my $onchange = 'this.form.submit()'; + $r->print('
'. + '
'.&mt('Domain').''. + &Apache::loncommon::select_dom_form($dom,'showdom','',1,$onchange,$incdoms). + '
'); + } } # @@ -4959,15 +4997,24 @@ sub print_textbook_form { # # Submit button # - $r->print(''. + $r->print(''. ''. ''); # # End request form # + + if (($crstype eq 'lti') && (ref($formhash) eq 'HASH')) { + foreach my $item (keys(%{$formhash})) { + $r->print(''."\n"); + } + } + $r->print(''); - &endContentScreen($r). + unless ($crstype eq 'lti') { + &endContentScreen($r); + } $r->print(&Apache::loncommon::end_page()); return; } @@ -5054,9 +5101,11 @@ sub clone_selection_table { } sub process_textbook_request { - my ($r,$dom,$action,$domdefs,$domconfig,$can_request) = @_; + my ($r,$dom,$action,$domdefs,$domconfig,$can_request,$crstype) = @_; my ($uniquecode,$req_notifylist); - my $crstype = 'textbook'; + if ($crstype eq '') { + $crstype = 'textbook'; + } if (ref($domconfig) eq 'HASH') { if (ref($domconfig->{'requestcourses'}) eq 'HASH') { if (ref($domconfig->{'requestcourses'}{'notify'}) eq 'HASH') { @@ -5097,24 +5146,34 @@ sub process_textbook_request { undef($clonedom); } } - $r->print(&header('Course Creation')); - - if (ref($can_request) eq 'HASH') { - unless ((scalar(keys(%{$can_request})) == 1) && ($can_request->{'textbook'})) { - &Apache::lonhtmlcommon::add_breadcrumb( - { href => '/adm/requestcourse', - text => 'Pick action', - }); + my $js = &processing_javascript(); + my ($loaditems,$args); + $loaditems = { + onload => 'javascript:hideProcessing();', + }; + if ($crstype eq 'lti') { + $args = { 'only_body' => 1}; + } + $r->print(&header('Course Creation',$js,$loaditems,undef,$args)); + + unless ($crstype eq 'lti') { + if (ref($can_request) eq 'HASH') { + unless ((scalar(keys(%{$can_request})) == 1) && ($can_request->{'textbook'})) { + &Apache::lonhtmlcommon::add_breadcrumb( + { href => '/adm/requestcourse', + text => 'Pick action', + }); + } } + &Apache::lonhtmlcommon::add_breadcrumb( + { href => '/adm/requestcourse', + text => "Create Course", + } + ); + &Apache::lonhtmlcommon::add_breadcrumb({text=>'Request Processed'}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course Requests','Course_Requests')); + &startContentScreen($r,'textbookrequests'); } - &Apache::lonhtmlcommon::add_breadcrumb( - { href => '/adm/requestcourse', - text => "Create Course", - } - ); - &Apache::lonhtmlcommon::add_breadcrumb({text=>'Request Processed'}); - $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course Requests','Course_Requests')); - &startContentScreen($r,'textbookrequests'); my $details = { owner => $env{'user.name'}, @@ -5166,7 +5225,21 @@ sub process_textbook_request { my ($result,$output,$customized) = &process_request($r,$lonhost,$dom,$cnum,$crstype,$now,$details, '',$req_notifylist,[],$domconfig); $r->print($output); - if (&Apache::loncoursequeueadmin::author_prompt()) { + if ($crstype eq 'lti') { + my $storecrs; + if ($env{'request.lti.login'}) { + my %lti = &Apache::lonnet::get_domain_lti($dom,'provider'); + if (ref($lti{$env{'request.lti.login'}}) eq 'HASH') { + $storecrs = $lti{$env{'request.lti.login'}}{'storecrs'}; + } + } + if ($storecrs) { + my %consumers = &Apache::lonnet::get_dom('lticonsumers',[$env{'form.sourcecrs'}],$dom); + if (($env{'form.lti.sourcecrs'} ne '') && ($consumers{$env{'form.lti.sourcecrs'}} eq '') && ($cnum ne '')) { + &Apache::lonnet::put_dom('lticonsumers',{ $env{'form.lti.sourcecrs'} => $cnum },$dom); + } + } + } elsif (&Apache::loncoursequeueadmin::author_prompt()) { unless ($customized) { &print_author_prompt($r,$action,$cnum,$dom,$crstype,$result); } @@ -5175,7 +5248,9 @@ sub process_textbook_request { $r->print('

'.&mt('Create another course').'

'); } } - &endContentScreen($r); + unless ($crstype eq 'lti') { + &endContentScreen($r); + } $r->print(&Apache::loncommon::end_page()); }