--- loncom/interface/lonpickcourse.pm 2014/03/11 21:42:18 1.110 +++ loncom/interface/lonpickcourse.pm 2017/01/05 16:17:11 1.125 @@ -1,7 +1,7 @@ # The LearningOnline Network # Pick a course # -# $Id: lonpickcourse.pm,v 1.110 2014/03/11 21:42:18 raeburn Exp $ +# $Id: lonpickcourse.pm,v 1.125 2017/01/05 16:17:11 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -36,26 +36,46 @@ use Apache::loncoursedata; use Apache::lonnet; use Apache::lonlocal; use Apache::longroup; -use Apache::courseclassifier; use LONCAPA qw(:DEFAULT :match); +use JSON::DWIW; sub handler { my $r = shift; + if ($env{'form.context'} eq 'adhoc') { + &Apache::loncommon::content_type($r,'application/json'); + $r->send_http_header; + my ($possroles,$description) = &Apache::lonnet::get_my_adhocroles($env{'form.cid'},1); + if ((ref($possroles) eq 'ARRAY') && (ref($description) eq 'HASH')) { + my $response = []; + if (@{$possroles}) { + foreach my $role (@{$possroles}) { + push(@{$response}, + { name => $role, + desc => $description->{$role}, + }); + } + } + $r->print(JSON::DWIW->to_json({roles => $response})); + } + return OK; + } &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK if $r->header_only; - + # ------------------------------------------------------------ Print the screen # Get parameters from query string &Apache::loncommon::get_unprocessed_cgi ($ENV{'QUERY_STRING'},['domainfilter','form','cnumelement', 'cdomelement','cnameelement','roleelement', - 'multiple','type','setroles','fixeddom','cloner']); + 'multiple','type','setroles','fixeddom','cloner', + 'crscode','crsdom']); my ($type,$title,$jscript,$multelement,$multiple,$roleelement,$typeelement, - $lastaction,$autosubmit,$submitopener,$cloneruname,$clonerudom); + $lastaction,$autosubmit,$submitopener,$cloneruname,$clonerudom,$crscode, + $crsdom,$rolechooser); - # Get course type - Course or Community. + # Get course type - Course, Community or Placement. $type = $env{'form.type'}; if (!defined($env{'form.type'})) { $type = 'Course'; @@ -69,12 +89,31 @@ sub handler { $title = 'Selecting '.$type.'(s)'; } - # if called when a DC is selecting a course - my $roledom = $env{'form.roleelement'}; + # if called when a DC or DH is selecting a course + my ($roledom,$rolename) = split(/:/,$env{'form.roleelement'}); if ($roledom) { - $roleelement = ''; + $roleelement = ''; $submitopener = &processpick(); - $autosubmit = 'process_pick("'.$roledom.'")'; + $autosubmit = 'process_pick("'.$roledom.'","'.$rolename.'")'; + if ($rolename eq 'dh') { + my %lt = &Apache::lonlocal::texthash( + title => 'Ad hoc role selection', + preamble => 'Please choose an ad hoc role in the course.', + cancel => 'Click "OK" to enter the course, or "Cancel" to choose a different course.', + ); + + $rolechooser = <<"END"; +
+

$lt{'preamble'}

+
+
+
+ +
+

$lt{'cancel'}

+
+END + } } if ($env{'form.typeelement'} ne '') { $typeelement = ''; @@ -83,12 +122,16 @@ sub handler { # if called when a DC is creating a course for another user. if ($env{'form.form'} eq 'ccrs') { ($cloneruname,$clonerudom) = ($env{'form.cloner'} =~ /^($match_username):($match_domain)$/); + $crscode = $env{'form.crscode'}; + $crsdom = $env{'request.role.domain'}; } # if called when requesting a course if ($env{'form.form'} eq 'requestcrs') { $cloneruname = $env{'user.name'}; $clonerudom = $env{'user.domain'}; + $crscode = $env{'form.crscode'}; + $crsdom = $env{'form.crsdom'}; } my $onlyown = 0; @@ -106,9 +149,22 @@ sub handler { if ((($env{'form.form'} eq 'cu') || ($env{'form.form'} eq 'studentform')) && ($env{'form.pickedcourse'})) { - $loaditem{'onload'} .= 'setDefaultCredits();setRoles();setSections();'; + if ($type ne 'Community') { + my %coursedescription = + &Apache::lonnet::coursedescription($env{'form.pickedcourse'}, + {'one_time' => '1'}); + my $cdom = $coursedescription{'domain'}; + my %domdefs = &Apache::lonnet::get_domain_defaults($cdom); + if (($domdefs{'officialcredits'} || $domdefs{'unofficialcredits'} || $domdefs{'textbookcredits'})) { + $loaditem{'onload'} .= 'setDefaultCredits();'; + } + } + $loaditem{'onload'} .= 'setRoles();setSections();'; + } + if ((($env{'form.gosearch'}) && ($env{'form.updater'} eq '')) && (!$onlyown)) { + $loaditem{'onload'} .= 'hideSearching(); '; } - my $js = &js_changer(); + my $js = &Apache::loncommon::js_changer(); $r->print(&Apache::loncommon::start_page($title,$js, {'add_entries' => \%loaditem, 'no_nav_bar' => 1, })); @@ -132,7 +188,8 @@ sub handler { # print javascript functions for choosing a course if ((($env{'form.gosearch'}) && ($env{'form.updater'} eq '')) || $onlyown) { - $r->print(&gochoose_javascript($type,$multiple,$autosubmit,$lastaction)); + $r->print(&gochoose_javascript($type,$multiple,$autosubmit,$lastaction, + $rolename,$rolechooser)); } $r->print(&Apache::lonhtmlcommon::scripttag($jscript)); $r->print($submitopener); @@ -141,8 +198,8 @@ sub handler { my $filter = {}; my $action = '/adm/pickcourse'; my ($numtitles,$showroles,$nohost,@codetitles); - if (!$onlyown) { - my $filterlist = ['domainfilter']; + unless ($onlyown) { + my $filterlist = ['domainfilter','sincefilter']; # created filter for DCs only if ($env{'user.adv'} && $env{'form.domainfilter'} && exists($env{'user.role.dc./'.$env{'form.domainfilter'}.'/'}) @@ -154,7 +211,15 @@ sub handler { } push(@{$filterlist},('descriptfilter','instcodefilter')); if ($env{'form.form'} eq 'rules') { - push(@{$filterlist},'personfilter'); + push(@{$filterlist},('personfilter','persondomfilter')); + if ($env{'form.persondomfilter'} eq '') { + unless ($env{'form.gosearch'}) { + $filter->{'persondomfilter'} = $env{'request.role.domain'}; + } + } else { + $filter->{'persondomfilter'} = + &LONCAPA::clean_domain($env{'form.persondomfilter'}); + } if (($env{'form.personfilter'} ne '') && ($env{'form.persondomfilter'} ne '')) { if (&Apache::lonnet::homeserver($env{'form.personfilter'}, $env{'form.persondomfilter'}) eq 'no_host') { @@ -164,7 +229,7 @@ sub handler { } } } else { - push(@{$filterlist},'ownerfilter'); + push(@{$filterlist},('ownerfilter','ownerdomfilter')); } # course ID filter for DCs only if ($env{'user.adv'} && $env{'form.domainfilter'} && @@ -174,10 +239,46 @@ sub handler { if ($cloneruname ne '' && $clonerudom ne '') { push(@{$filterlist},'cloneableonly'); } - - $r->print(&build_filters($filterlist,$type,$roleelement,$multelement, - $filter,$action,\$numtitles,undef,$cloneruname, - $clonerudom,$typeelement,\@codetitles)); + if ((ref($filterlist) eq 'ARRAY') && (ref($filter) eq 'HASH')) { + foreach my $item (@{$filterlist}) { + $filter->{$item} = $env{'form.'.$item}; + } + } + if ($env{'form.form'} eq 'portform') { + $filter->{'domainfilter'} ||= $env{'user.domain'}; + } elsif ($env{'form.form'} eq 'studentform') { + $filter->{'domainfilter'} ||= $env{'request.role.domain'}; + } + my $codedom; + if ($env{'form.fixeddom'}) { + $codedom = $env{'request.role.domain'}; + } else { + $codedom = $filter->{'domainfilter'}; + } + my ($clonetext,$clonewarning); + if (($env{'form.form'} eq 'ccrs') || ($env{'form.form'} eq 'requestcrs')) { + (my $coord_cloneable,$clonewarning) = + &get_coordinator_cloneable($cloneruname,$clonerudom,$type); + if ($env{'form.form'} eq 'ccrs') { + $clonetext = ''."\n"; + } + if ($coord_cloneable) { + $clonetext .= ''; + } + if ($crscode ne '') { + $clonetext .= ''; + } + if ($crsdom ne '') { + $clonetext .= ''; + } + } + $r->print(&Apache::loncommon::build_filters($filterlist,$type,$roleelement,$multelement, + $filter,$action,\$numtitles,undef,$cloneruname, + $clonerudom,$typeelement,\@codetitles,$codedom, + $env{'form.form'},$env{'form.fixeddom'}, + $env{'form.prevphase'},$env{'form.cnameelement'}, + $env{'form.cnumelement'},$env{'form.cdomelement'}, + $env{'form.setroles'},$clonetext,$clonewarning)); } # ---------------------------------------------------------------- Get the data @@ -190,8 +291,22 @@ sub handler { $domcloner = 1; } } - my %courses = &search_courses($r,$type,$onlyown,$filter,$numtitles, - $cloneruname,$clonerudom,$domcloner,\@codetitles); + my %courses; + if (!$onlyown) { + $r->print('
'.&mt('Searching ...').'
'); + $r->rflush(); + my $srchdom = $filter->{'domainfilter'}; + %courses = &Apache::loncommon::search_courses($srchdom,$type,$filter,$numtitles, + $cloneruname,$clonerudom,$domcloner, + \@codetitles,$env{'form.cc_clone'}, + $crsdom,$crscode); + } else { + $r->print('
'); + my %coursehash = &Apache::loncommon::findallcourses(); + foreach my $cid (sort(keys(%coursehash))) { + $courses{$cid}{'description'} = $env{'course.'.$cid.'.description'}; + } + } if ($nohost) { $r->print (''. &mt('User does not exist - username: [_1], domain: [_2].', @@ -199,29 +314,13 @@ sub handler { ''.$filter->{'persondomfilter'}.'').''); } else { &display_matched_courses($r,$type,$multiple,$action,$showroles,$cloneruname, - $clonerudom,%courses); + $clonerudom,$crsdom,$crscode,%courses); } } $r->print(&Apache::loncommon::end_page()); return OK; } -sub js_changer { - return < -// - - -ENDJS -} - sub processpick { my $openerform = 'rolechoice'; if ($env{'form.form'} eq 'studentform') { @@ -229,7 +328,7 @@ sub processpick { } my $process_pick = <<"ENDONE"; '."\n"; - } - } - if ($instcodeform eq '') { - $instcodeform = - ''; - $instcodetitle = $lt{'ins'}; - } else { - $instcodetitle = $lt{'inc'}; - } - if ($env{'form.fixeddom'}) { - $instcodetitle .= '
('.$codedom.')'; - } - } - } - - my $output = qq| -
- -|; - if ($formname eq 'modifycourse') { - $output .= ''."\n". - ''."\n"; - } else { - my $name_input; - if ($env{'form.cnameelement'} ne '') { - $name_input = ''; - } - $output .= qq| - - -$name_input -$roleelement -$multelement -$typeelement -|; - if ($formname eq 'portform') { - $output .= ''."\n"; - } - } - if ($env{'form.fixeddom'}) { - $output .= ''."\n"; - } - $output .= "
\n".&Apache::lonhtmlcommon::start_pick_box(); - if ($sincefilterform) { - $output .= &Apache::lonhtmlcommon::row_title($lt{'cac'}) - .$sincefilterform - .&Apache::lonhtmlcommon::row_closure(); - } - if ($createdfilterform) { - $output .= &Apache::lonhtmlcommon::row_title($lt{'ccr'}) - .$createdfilterform - .&Apache::lonhtmlcommon::row_closure(); - } - if ($domainselectform) { - $output .= &Apache::lonhtmlcommon::row_title($lt{'cdo'}) - .$domainselectform - .&Apache::lonhtmlcommon::row_closure(); - } - if ($typeselectform) { - if (($env{'form.form'} eq 'ccrs') || ($env{'form.form'} eq 'requestcrs')) { - $output .= $typeselectform; - } else { - $output .= &Apache::lonhtmlcommon::row_title($lt{'cog'}) - .$typeselectform - .&Apache::lonhtmlcommon::row_closure(); - } - } - if ($instcodeform) { - $output .= &Apache::lonhtmlcommon::row_title($instcodetitle) - .$instcodeform - .&Apache::lonhtmlcommon::row_closure(); - } - if (exists($filter->{'ownerfilter'})) { - $output .= &Apache::lonhtmlcommon::row_title($lt{'cow'}). - '
'.&mt('Username').'
'. - '
'.&mt('Domain').'
'. - $ownerdomselectform.'
'. - &Apache::lonhtmlcommon::row_closure(); - } - if (exists($filter->{'personfilter'})) { - $output .= &Apache::lonhtmlcommon::row_title($lt{'cop'}). - '
'.&mt('Username').'
'. - '
'.&mt('Domain').'
'. - $persondomselectform.'
'. - &Apache::lonhtmlcommon::row_closure(); - } - if (exists($filter->{'coursefilter'})) { - $output .= &Apache::lonhtmlcommon::row_title(&mt('LON-CAPA course ID')) - .'' - .&Apache::lonhtmlcommon::row_closure(); - } - if ($cloneableonlyform) { - $output .= &Apache::lonhtmlcommon::row_title($cloneabletitle). - $cloneableonlyform.&Apache::lonhtmlcommon::row_closure(); - } - if (exists($filter->{'descriptfilter'})) { - $output .= &Apache::lonhtmlcommon::row_title($lt{'cde'}) - .'' - .&Apache::lonhtmlcommon::row_closure(1); - } - $output .= &Apache::lonhtmlcommon::end_pick_box().'

'; - my ($coord_cloneable,$warning); - if (($env{'form.form'} eq 'ccrs') || ($env{'form.form'} eq 'requestcrs')) { - ($coord_cloneable,$warning) = - &get_coordinator_cloneable($cloneruname,$clonerudom,$type); - if ($env{'form.form'} eq 'ccrs') { - $output .= ''."\n"; - } - if ($coord_cloneable) { - $output .= ''; - } - } - $output .= ''."\n". - '

'."\n".'
'."\n".'
'."\n"; - return $jscript.$warning.$output; -} - -sub timebased_select_form { - my ($item,$filter) = @_; - if (ref($filter) eq 'HASH') { - $filter->{$item} = $env{'form.'.$item}; - $filter->{$item} =~ s/[^\d-]//g; - if (!$filter->{$item}) { $filter->{$item}=-1; } - return &Apache::loncommon::select_form( - $filter->{$item}, - $item, - { '-1' => '', - '86400' => &mt('today'), - '604800' => &mt('last week'), - '2592000' => &mt('last month'), - '7776000' => &mt('last three months'), - '15552000' => &mt('last six months'), - '31104000' => &mt('last year'), - 'select_form_order' => - ['-1','86400','604800','2592000','7776000', - '15552000','31104000']}); - } -} - sub get_coordinator_cloneable { my ($cloneruname,$clonerudom,$type) = @_; if (($cloneruname!~/\w/) || ($clonerudom!~/\w/)) { @@ -860,7 +807,7 @@ sub get_coordinator_cloneable { my ($cc_clone,$ccrole); if ($type eq 'Community') { $ccrole = 'co'; - } elsif ($type eq 'Course') { + } else { $ccrole = 'cc'; } my %ccroles = &Apache::lonnet::get_my_roles($cloneruname,$clonerudom, @@ -874,102 +821,6 @@ sub get_coordinator_cloneable { } } -sub search_courses { - my ($r,$type,$onlyown,$filter,$numtitles,$cloneruname,$clonerudom,$domcloner,$codetitles) = @_; - my (%courses,%showcourses,$cloner,$ccrole); - if ($type eq 'Community') { - $ccrole = 'co'; - } else { - $ccrole = 'cc'; - } - if (!$onlyown) { - $r->print('
'.&mt('Searching ...').'
'); - $r->rflush(); - if (($filter->{'ownerfilter'} ne '') || - ($filter->{'ownerdomfilter'} ne '')) { - $filter->{'combownerfilter'} = $filter->{'ownerfilter'}.':'. - $filter->{'ownerdomfilter'}; - } - foreach my $item ('descriptfilter','coursefilter','combownerfilter') { - if (!$filter->{$item}) { - $filter->{$item}='.'; - } - } - my $now = time; - my $timefilter = - ($filter->{'sincefilter'}==-1?1:$now-$filter->{'sincefilter'}); - my ($createdbefore,$createdafter); - if (($filter->{'createdfilter'} ne '') && ($filter->{'createdfilter'} !=-1)) { - $createdbefore = $now; - $createdafter = $now-$filter->{'createdfilter'}; - } - my ($instcodefilter,$regexpok); - if ($numtitles) { - if ($env{'form.official'} eq 'on') { - $instcodefilter = - &Apache::courseclassifier::instcode_search_str($filter->{'domainfilter'},$numtitles,$codetitles); - $regexpok = 1; - } elsif ($env{'form.official'} eq 'off') { - $instcodefilter = &Apache::courseclassifier::instcode_search_str($filter->{'domainfilter'},$numtitles,$codetitles); - unless ($instcodefilter eq '') { - $regexpok = -1; - } - } - } else { - $instcodefilter = $filter->{'instcodefilter'}; - } - if ($instcodefilter eq '') { $instcodefilter = '.'; } - if ($type eq '') { $type = '.'; } - - if (($clonerudom ne '') && ($cloneruname ne '')) { - $cloner = $cloneruname.':'.$clonerudom; - } - %courses = - &Apache::lonnet::courseiddump($filter->{'domainfilter'}, - $filter->{'descriptfilter'}, - $timefilter, - $instcodefilter, - $filter->{'combownerfilter'}, - $filter->{'coursefilter'}, - undef,undef,$type,$regexpok,undef,undef, - undef,undef,$cloner,$env{'form.cc_clone'}, - $filter->{'cloneableonly'}, - $createdbefore,$createdafter,undef, - $domcloner); - if (($filter->{'personfilter'} ne '') && ($filter->{'persondomfilter'} ne '')) { - my %rolehash = &Apache::lonnet::get_my_roles($filter->{'personfilter'}, - $filter->{'persondomfilter'}, - 'userroles',undef, - [$ccrole,'in','ad','ep','ta','cr'], - $filter->{'domainfilter'}); - foreach my $role (keys(%rolehash)) { - my ($cnum,$cdom,$courserole) = split(':',$role); - my $cid = $cdom.'_'.$cnum; - if (exists($courses{$cid})) { - if (ref($courses{$cid}) eq 'HASH') { - if (ref($courses{$cid}{roles}) eq 'ARRAY') { - if (!grep(/^\Q$courserole\E$/,@{$courses{$cid}{roles}})) { - push (@{$courses{$cid}{roles}},$courserole); - } - } else { - $courses{$cid}{roles} = [$courserole]; - } - $showcourses{$cid} = $courses{$cid}; - } - } - } - %courses = %showcourses; - } - } else { - $r->print('
'); - my %coursehash = &Apache::loncommon::findallcourses(); - foreach my $cid (sort(keys(%coursehash))) { - $courses{$cid}{'description'} = $env{'course.'.$cid.'.description'}; - } - } - return %courses; -} - sub course_chooser { my ($multiple,$cdom,$cnum,$cleandesc,$canclone) = @_; my $output; @@ -977,7 +828,7 @@ sub course_chooser { $output = '  ") + .appendTo("#LC_choose_adhoc"); + } + \$( "#LC_get_role_0").prop("checked", true); + \$( "#LC_adhocrole_chooser" ).dialog({ autoOpen: false }); + \$( "#LC_adhocrole_chooser" ).dialog("open"); + \$( "#LC_adhocrole_chooser" ).dialog({ + height: 400, + width: 500, + modal: true, + resizable: false, + buttons: [ + { + text: "$lt{'ok'}", + click: function() { + var rolename = \$('input[name=LC_get_role]:checked', '#LChelpdeskpicker').val(); + process_pick(cdom,rolename); + \$("#LC_adhocrole_chooser").dialog( "close" ); + $lastaction; + } + }, + { + text: "$lt{'exit'}", + click: function() { + \$("#LC_adhocrole_chooser").dialog( "close" ); + } + } + ], + }); + \$( "#LC_adhocrole_chooser" ).find( "form" ).on( "submit", function( event ) { + event.preventDefault(); + var rolename = \$('input[name=LC_get_role]:checked', '#LChelpdeskpicker').val() + process_pick(cdom,rolename); + \$("#LC_adhocrole_chooser").dialog( "close" ); + $lastaction; + }); + } + } + } } -|; - return &Apache::lonhtmlcommon::scripttag($output); +http.send(params); + } else { + $autosubmit + $lastaction + } +} + +ENDJS + return $rolechooser.&Apache::lonhtmlcommon::scripttag($output); } 1; @@ -1122,7 +1059,7 @@ Course Activity - how recently was cours Course Domain - the domain of the course =item * -Type - Course or Community +Type - Course, Community or Placement =item * Course Institutional Code - the institutional identifier assigned to the course @@ -1175,7 +1112,7 @@ Following selection, and/or submission, X B: -Input: 1 - $type - the course type - Course or Community +Input: 1 - $type - the course type - Course, Community, or Placement Output: 1 - $output - javascript wrapped in EscriptEE/scriptE tags @@ -1186,9 +1123,9 @@ javascript code for reporting selected s =item * X -B: +B: -Input: 7 - request object, course type, multiple (0 or 1), form action, whether to show roles (for course personnel filter), username of new course owner, domain of new course owner, hash of courses. +Input: 8 - request object, course type, multiple (0 or 1), form action, whether to show roles (for course personnel filter), username of new course owner, domain of new course owner, domain of new course, institutional code of new course, hash of courses. Output: 0 @@ -1205,30 +1142,6 @@ Output: 2 - $jscript - javascript for ch Side Effects: None -=item * -X -B: - - -Input: 12 - anonymous array of search criteria; course type; $roleelement ; $multelement ; anonymous hash of criteria and their values; form action; ref to scalar (count of number of elements in institutional codes -- e.g., 4 for year, semester, department, and number); caller context (e.g., set to 'modifycourse' when routine is called from lonmodifycourse.pm); username and domain of new course owner who wants to clone, $typeelem; reference to array of titles of components in institutional codes (official courses). - -Output: 1 - $output - HTML for display of search criteria, and hidden form elements. - -Side Effects: None - -=item * -X -B: - - -Input: 9 - request object, course type, search scope: only courses in which user has active role (1), or any course (0); anonymous hash of criteria and their values; for institutional codes - number of categories; optional username of new course owner, optional domain of new course owner). Seventh and eighth needed when search is for courses to clone from course request form, or course creation form (DC). Optional "domcloner" flag (has value=1 if user has ccc priv in -domain being filtered by (used when DC is using course creation form). Ninth is reference to array of titles of components in institutional codes (official courses). - -Output: 1 - %courses - hash of courses satisfying search criteria, keys = course IDs, values are corresponding colon-separated escaped description, institutional code, owner and type. - -Side Effects: None - =item * X @@ -1243,9 +1156,9 @@ Side Effects: None =item * X -B: +B: -Input: 4 - course type; single (0) or multiple courses (1); in context of DC selecting a CC role in a course: javascript code from &processpick(); final action to take after user chooses course(s): either close window, or submit form for display of next page etc. +Input: 5 - course type; single (0) or multiple courses (1); in context of DC selecting a CC role in a course: javascript code from &processpick(); final action to take after user chooses course(s): either close window, or submit form for display of next page etc.; rolename (e.g., dh) of user's current role. Output: 1 $output - javascript wrapped in EscriptEE/scriptE tags