--- loncom/interface/lonrequestcourse.pm 2010/11/08 21:16:24 1.41.2.7 +++ loncom/interface/lonrequestcourse.pm 2023/03/11 04:54:24 1.95.2.7.2.3 @@ -1,7 +1,7 @@ # The LearningOnline Network # Request a course # -# $Id: lonrequestcourse.pm,v 1.41.2.7 2010/11/08 21:16:24 raeburn Exp $ +# $Id: lonrequestcourse.pm,v 1.95.2.7.2.3 2023/03/11 04:54:24 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -94,8 +94,6 @@ described at http://www.lon-capa.org. =item print_request_outcome() -=item get_processtype() - =item check_autolimit() =item retrieve_settings() @@ -121,6 +119,10 @@ use Apache::loncoursequeueadmin; use Apache::lonuserutils; use LONCAPA qw(:DEFAULT :match); +my $registered_flush; +my $registered_instcats; +my $modified_dom; + sub handler { my ($r) = @_; &Apache::loncommon::content_type($r,'text/html'); @@ -129,30 +131,101 @@ sub handler { return OK; } + $registered_flush = 0; + $registered_instcats = 0; + $modified_dom = ''; + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['action','showdom','cnum','state','crstype']); + ['action','showdom','cnum','state','crstype','queue','tabs']); &Apache::lonhtmlcommon::clear_breadcrumbs(); my $dom = &get_course_dom(); my $action = $env{'form.action'}; my $state = $env{'form.state'}; my (%states,%stored); - my ($jscript,$uname,$udom,$result,$warning); + my ($jscript,$uname,$udom,$result,$warning,$showcredits,$instcredits,%can_request, + %request_domains,@incdoms); + my %domdefs = &Apache::lonnet::get_domain_defaults($dom); + if ($domdefs{'officialcredits'} || $domdefs{'unofficialcredits'} || $domdefs{'textbookcredits'}) { + $showcredits = 1; + } + + my $canreq = + &Apache::lonnet::check_can_request($dom,\%can_request,\%request_domains); + + foreach my $item (keys(%request_domains)) { + if (ref($request_domains{$item}) eq 'ARRAY') { + foreach my $possdom (@{$request_domains{$item}}) { + unless(grep(/^\Q$possdom\E$/,@incdoms)) { + push(@incdoms,$possdom); + } + } + } + } + + if ($canreq) { + if (($env{'form.crstype'} eq 'textbook') || + (scalar(keys(%can_request)) == 1) && ($can_request{'textbook'})) { + my %domconfig = &Apache::lonnet::get_dom('configuration',['requestcourses'],$dom); + if ($action eq 'log') { + my $usetabs; + if ((scalar(keys(%can_request)) == 1) && ($can_request{'textbook'})) { + $usetabs = 1; + } elsif ($env{'form.tabs'} eq 'on') { + $usetabs = 1; + } + &Apache::lonhtmlcommon::add_breadcrumb({text=>'Course Request'}); + my $crumb = &Apache::lonhtmlcommon::breadcrumbs('Course Requests','Course_Requests'); + &print_request_logs($r,$dom,undef,undef,$crumb,$usetabs); + } elsif ($action eq 'process') { + if ($can_request{'textbook'}) { + &process_textbook_request($r,$dom,$action,\%domdefs,\%domconfig,\%can_request); + } else { + &textbook_request_disabled($r,$dom,$action,\%can_request); + } + } elsif ($action eq 'display') { + my ($uname,$udom,$result,$warning) = &domcoord_display($dom); + if ($warning ne '') { + my $args = { only_body => 1 }; + $r->print(&header('Course/Community Requests','','' ,'',$args). + '
'.&mt('Deployment of a Concept Test requires completion of the following three steps:').'
'.&mt('When assembling a test you may:').
- '
'.&mt('(a) have a valid test built automatically by the WebCenter, or').'
'.&mt('(b) select the questions to include by combining questions chosen from eleven bins with four mandatory questions, or').
- '
'.&mt('(c) copy one of your existing tests (including optional copying of the student roster)').'
'.&mt('The most efficient way to enroll students is to upload a text file containing usernames and passwords.').'
'.&mt("Students' full e-mail addresses should be used as their usernames to ensure uniqueness.").'
'.$pageinfo.'
'); + if ($earlyout) { + $r->print(&Apache::loncommon::end_page()); return; } - - my @incdoms; - if (ref($request_domains) eq 'HASH') { - foreach my $item (keys(%{$request_domains})) { - if (ref($request_domains->{$item}) eq 'ARRAY') { - foreach my $possdom (@{$request_domains->{$item}}) { - unless(grep(/^\Q$possdom\E$/,@incdoms)) { - push(@incdoms,$possdom); - } - } - } - } - } - $r->print(&header($pagetitle,$js.$jscript,$loaditems).$crumb. - ''.$pageinfo.'
'. - ''); if ($storeresult eq 'ok') { - $r->print(''. - &mt('Modify this request').''.(' 'x4)); + $r->print('
'. + &mt('Modify this request').''.(' 'x4). + ''.&mt('Make another request').'
'); + } + if (&Apache::loncoursequeueadmin::author_prompt()) { + unless ($customized) { + &print_author_prompt($r,$env{'form.action'},$env{'form.cnum'},$env{'form.showdom'}, + $env{'form.crstype'},$storeresult); + } + } elsif ($storeresult eq 'created') { + unless ($customized) { + $r->print(''.&mt('Make another request').'
'); + } + } + } + } elsif ($state eq 'reqauthor') { + my ($result,@links); + if ($env{'form.requestauthor'}) { + $r->print(&Apache::loncoursequeueadmin::process_reqauthor(\$result)); + if ($result eq 'created') { + my $role = 'au'; + my $spec = "$role./$env{'form.showdom'}/"; + push(@links,&mt('Enter your Authoring Space with role: [_1]', + ''. + &Apache::lonnet::plaintext($role).'')); } - unless ($env{'form.concepttest'}) { - $r->print(''.&mt('Make another request').''); + } + if (($env{'form.disposition'} eq 'created') && + ($env{'form.cnum'} =~ /^$match_courseid$/) && + ($env{'form.showdom'} =~ /^$match_domain$/)) { + my ($spec,$area,$role,$type); + my $role = 'cc'; + my $spec = "$role./$env{'form.showdom'}/$env{'form.cnum'}"; + my $type = 'Course'; + if ($env{'form.crstype'} eq 'community') { + $type = 'Community'; } - return; + my $showrole = &Apache::lonnet::plaintext($role,$type); + unshift(@links,&mt('Enter new course with role: [_1]', + ''.$showrole.'')); + } + if (@links > 1) { + $r->print(&mt('New roles will be listed on your [_1]Roles[_2] page.', + '','').' '.&mt('Choose a role:'). + ''.$links[0].'
'); } } - my @excluded = &get_excluded_elements($dom,$states,$action,$state); + my @excluded = &get_excluded_elements($dom,$states,$action,$state,$showcredits); if ($state eq 'personnel') { push(@excluded,'persontotal'); } @@ -1506,25 +1652,51 @@ sub print_request_form { $count ++; } $env{'form.persontotal'} = $count; - } } if ($state eq 'enrollment') { - push(@excluded,'crosslisttotal'); + push(@excluded,('sectotal','crosslisttotal')); + } + if (($state eq 'process') || ($state eq 'reqauthor')) { + $r->print(''); + } else { + $r->print(&Apache::lonhtmlcommon::echo_form_input(\@excluded).''); + &display_navbuttons($r,$dom,$formname,$prev,$navtxt{'prev'},$next, + $navtxt{'next'},$state); } - $r->print(&Apache::lonhtmlcommon::echo_form_input(\@excluded).''); - &display_navbuttons($r,$dom,$formname,$prev,$navtxt{'prev'},$next, - $navtxt{'next'},$state); return; } -sub get_cancreate_status { - my ($persondom,$personname,$dom) = @_; +sub print_author_prompt { + my ($r,$action,$cnum,$showdom,$crstype,$storeresult) = @_; + $r->print(''.
+ &mt('Although assessment items can be created directly inside a course, such items only use part of the assessment capabilities of LON-CAPA.').
+ '
'.
+ &mt('By contrast, items created in Authoring Space, then imported into a course, can use all of the features of the assessment engine.').'
'.&mt('Request Authoring Space access now?'). + ' '. + ''. + (' 'x2). + ''. + '
'. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''.
+ ''.&mt('Records/page:').' '. + &Apache::lonmeta::selectbox('show',$curr->{'show'},undef, + (&mt('all'),5,10,20,50,100,1000,10000)). + ' | '; + my $startform = + &Apache::lonhtmlcommon::date_setter($formname,'requested_after_date', + $curr->{'requested_after_date'},undef, + undef,undef,undef,undef,undef,undef,$nolink); + my $endform = + &Apache::lonhtmlcommon::date_setter($formname,'requested_before_date', + $curr->{'requested_before_date'},undef, + undef,undef,undef,undef,undef,undef,$nolink); + $output .= ' | '.&mt('Window during which course/community was requested:').' '. + '
| '.
+ ''; + my ($types,$typenames) = &Apache::loncommon::course_types(); + if (ref($types) eq 'ARRAY') { + if (@{$types} > 1) { + $output .= ' | '.
+ &mt('Course Type:').' | ';
+ }
+ }
+ my ($statuses,$statusnames) = &reqstatus_names($curr->{'crstype'});
+ if (ref($statuses) eq 'ARRAY') {
+ if (@{$statuses} > 1) {
+ $output .= ''.
+ &mt('Request Status:').' | ';
+ }
+ }
+ $output .= '
'. + ''. + '
'.&mt('Your course request has been processed and the course has been created.');
}
- if ($dom eq 'gcitest') {
- my $caller = 'requestcrs';
- &acquire_cc_role($dom,$cnum,'cc./'.$dom.'/'.$cnum);
- my %parmresult =
- &store_crsparms($dom,$cnum,$now,$accessstart,$accessend);
- &Apache::londocsgci::setdefaults();
- my %crsenvhash = (
- suppress_tries => 'yes',
- );
- my $putresult = &Apache::lonnet::put('environment',\%crsenvhash,$dom,$cnum);
- if ($env{'form.concepttest'} eq 'cloning') {
- &Apache::lonuserstate::readmap($dom.'/'.$cnum);
- if (($clonecrs) && ($clonedom eq 'gcitest')) {
- my $cloneid = $clonedom.'/'.$clonecrs;
- my %clonedesc = &Apache::lonnet::coursedescription($cloneid,{'one_time' => 1});
- my $oldcdesc = $clonedesc{'description'};
- $output .= '
'.&mt('A concept test has been copied from your existing test: [_1].',''.$oldcdesc.'').'
'.$logging[-1].'
'; - } - } - $output .= ''.$logmsg.'
'; + } + if ((ref($clonemsg) eq 'ARRAY') && (@{$clonemsg})) { + $output .= '';
+ my $user_lh = &Apache::loncommon::user_lang($env{'user.name'},$env{'user.domain'});
+ foreach my $item (@{$clonemsg}) {
+ if (ref($item) eq 'HASH') {
+ $output .= &mt_user($user_lh,$item->{mt},
+ @{$item->{args}}).'
'."\n";
+ }
+ }
+ $output .= '
'.&mt('Your community request has been updated').'
'; - } else { - $output .= ''.&mt('Your course request has been updated').'
'; + if ($modified && $queued) { + if ($crstype eq 'community') { + $output .= ''.&mt('Your community request has been updated').'
'; + } else { + $output .= ''.&mt('Your course request has been updated').'
'; + } + if ($disposition eq 'approval') { + $output .= ¬ification_information($disposition,$req_notifylist,$dom,$cnum,$now); + } + } + if ($disposition eq 'approval') { + if ((ref($postprocess) eq 'HASH') && + ((ref($postprocess->{'queuedmsg'}) eq 'HASH') || ($postprocess->{'queuedweb'}))) { + ¬ification_information($disposition,undef,$dom,$cnum,$now,undef,$postprocess); + $customized = $postprocess->{'createdcustomized'}; + } + } elsif ($disposition eq 'pending') { + my $pendingform; + if ($crstype ne 'official') { + $pendingform = &pending_validation_form($r,$dom,$cnum,$crstype,$now,$token, + $lonhost,$env{'form.cdescr'}); + } + if ($pendingform) { + $output .= $pendingform; + } else { + $output .= ¬ification_information($disposition,undef,$dom,$cnum,$now,undef,$postprocess); + } + if (ref($postprocess) eq 'HASH') { + $customized = $postprocess->{'createdcustomized'}; + } } - $output .= ¬ification_information($disposition,$req_notifylist,$cnum,$now); } if ($validationerror ne '') { - $output .= ''.&mt('An error occurred validating your request with institutional data sources: [_1].',$validationerror).''; + $output .= ''.&mt('An error occurred validating your request with institutional data sources: [_1].',$validationerror).'
'; + } + if ($updateresult) { + $output .= $updateresult; } } if ($creationresult ne '') { - return ($creationresult,$output); + return ($creationresult,$output,$customized); } else { - return ($storeresult,$output); + return ($storeresult,$output,$customized); + } +} + +sub devalidate_remote_instcats { + if ($modified_dom ne '') { + my %servers = &Apache::lonnet::internet_dom_servers($modified_dom); + my %thismachine; + map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids(); + if (keys(%servers)) { + foreach my $server (keys(%servers)) { + next if ($thismachine{$server}); + &Apache::lonnet::remote_devalidate_cache($server,['instcats:'.$modified_dom]); + } + } + $modified_dom = ''; + } + return; +} + +sub custom_formitems { + my ($preprocess,$customhash) = @_; + return unless ((ref($preprocess) eq 'HASH') && (ref($customhash) eq 'HASH')); + if (ref($preprocess->{'formitems'}) eq 'HASH') { + foreach my $key (keys(%{$preprocess->{'formitems'}})) { + if ($preprocess->{'formitems'}->{$key} eq 'multiple') { + if (exists($env{'form.'.$key})) { + my @items = &Apache::loncommon::get_env_multiple($env{'form.'.$key}); + foreach my $item (@items) { + $item =~ s/(`)/'/g; + $item =~ s/\$/\(\$\)/g; + push(@{$customhash->{$key}},$item); + } + } + } else { + if (exists($env{'form.'.$key})) { + $customhash->{$key} = $env{'form.'.$key}; + $customhash->{$key} =~ s/(`)/'/g; + $customhash->{$key} =~ s/\$/\(\$\)/g; + } + } + } } } @@ -3438,98 +4239,8 @@ sub update_requestors_roles { return $output; } -sub acquire_cc_role { - my ($cdom,$cnum,$trolecode,$csec) = @_; - my %coursegroups = &Apache::lonnet::get_active_groups( - $env{'user.domain'},$env{'user.name'},$cdom, $cnum); - my $cgrps = join(':',keys(%coursegroups)); - if ($env{'environment.recentroles'}) { - my %frozen_roles = - &Apache::lonhtmlcommon::get_recent_frozen('roles',$env{'environment.recentrolesn'}); - &Apache::lonhtmlcommon::store_recent('roles',$trolecode,' ', - $frozen_roles{$trolecode}); - } - - &Apache::lonnet::appenv({"request.course.id" => '', - "request.course.fn" => '', - "request.course.uri" => '', - "request.course.sec" => '', - "request.role" => 'cm', - "request.role.adv" => $env{'user.adv'}, - "request.role.domain" => $env{'user.domain'}}); - - &Apache::lonnet::log($env{'user.domain'}, - $env{'user.name'}, - $env{'user.home'}, - "Role ".$trolecode); - - &Apache::lonnet::appenv( - {'request.role' => $trolecode, - 'request.role.domain' => $cdom, - 'request.course.sec' => $csec, - 'request.course.groups' => $cgrps}); - my ($furl,$ferr) = &Apache::lonuserstate::readmap($cdom.'/'.$cnum); - my $tadv; - if (&Apache::lonnet::allowed('adv') eq 'F') { $tadv=1; } - &Apache::lonnet::appenv({'request.role.adv'=>$tadv}); - return; -} - -sub store_crsparms { - my ($cdom,$cnum,$now,$accessstart,$accessend) = @_; - my $topsymb = '___0___uploaded/'.$cdom.'/'.$cnum.'/default.sequence'; - my %crsparms = ( - buttonshide => { - value => 'yes', - type => 'string_yesno', - }, - opendate => { - value => $accessstart, - type => 'date_start', - }, - duedate => { - value => $accessend, - type => 'date_end', - }, - problemstatus => { - value => 'no', - type => 'string_problemstatus', - }, - maxtries => { - value => '1', - type => 'intpos', - }, - discussend => { - value => $now, - type => 'date_end', - }, - discusshide => { - value => 'yes', - type => 'string_yesno', - } - ); - my %parmresult; - foreach my $item (keys(%crsparms)) { - $parmresult{$item} = - &Apache::lonparmset::storeparm_by_symb($topsymb, - '0_'.$item,14,$crsparms{$item}{'value'}, - $crsparms{$item}{'type'},undef,$cdom); - } - return %parmresult; -} - -sub roster_upload_form { - my ($r,$output) = @_; - $r->print(''.&mt('If you have a text file available containing student e-mail addresses and initial passwords, you may upload it now.').'
'.
- &mt('You may also enroll students at a later date by visiting the [_1]"Menu"[_2] page and choosing: [_1]"Manage Enrollment"[_2].','','').'
'.
+ &mt('Students can automatically select your course by entering this code: [_1].',''.$code.'').
+ '
'.
+ &mt('A message has been sent to your LON-CAPA account with this information.');
+ if ($address ne '') {
+ $output.= '
'.&mt('An e-mail has also been sent to: [_1] with this code.',$address);
+ }
+ $output .= '