--- loncom/interface/lonpickcourse.pm 2010/03/08 14:43:46 1.93 +++ loncom/interface/lonpickcourse.pm 2013/07/15 14:32:45 1.108 @@ -1,7 +1,7 @@ # The LearningOnline Network # Pick a course # -# $Id: lonpickcourse.pm,v 1.93 2010/03/08 14:43:46 raeburn Exp $ +# $Id: lonpickcourse.pm,v 1.108 2013/07/15 14:32:45 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -31,6 +31,7 @@ package Apache::lonpickcourse; use strict; use Apache::Constants qw(:common); use Apache::loncommon; +use Apache::lonhtmlcommon; use Apache::loncoursedata; use Apache::lonnet; use Apache::lonlocal; @@ -105,7 +106,7 @@ sub handler { if ((($env{'form.form'} eq 'cu') || ($env{'form.form'} eq 'studentform')) && ($env{'form.pickedcourse'})) { - $loaditem{'onload'} .= 'setRoles();setSections();'; + $loaditem{'onload'} .= 'setDefaultCredits();setRoles();setSections();'; } my $js = &js_changer(); $r->print(&Apache::loncommon::start_page($title,$js, @@ -133,17 +134,25 @@ sub handler { $onlyown) { $r->print(&gochoose_javascript($type,$multiple,$autosubmit,$lastaction)); } - $r->print(''); + $r->print(&Apache::lonhtmlcommon::scripttag($jscript)); $r->print($submitopener); # ------------------------------------------ Display of filters to limit search my $filter = {}; my $action = '/adm/pickcourse'; - my ($numtitles,$showroles,$nohost); + my ($numtitles,$showroles,$nohost,@codetitles); if (!$onlyown) { - my $filterlist = ['domainfilter','descriptfilter', - 'instcodefilter']; + my $filterlist = ['domainfilter']; + # created filter for DCs only + if ($env{'user.adv'} && $env{'form.domainfilter'} && + exists($env{'user.role.dc./'.$env{'form.domainfilter'}.'/'}) + && $env{'form.form'} ne 'portform') { + my $loncaparev = &Apache::lonnet::get_server_loncaparev($env{'form.domainfilter'}); + if ($loncaparev ne 'unknown_cmd') { + push(@{$filterlist},'createdfilter'); + } + } + push(@{$filterlist},('descriptfilter','instcodefilter')); if ($env{'form.form'} eq 'rules') { push(@{$filterlist},'personfilter'); if (($env{'form.personfilter'} ne '') && ($env{'form.persondomfilter'} ne '')) { @@ -168,14 +177,21 @@ sub handler { $r->print(&build_filters($filterlist,$type,$roleelement,$multelement, $filter,$action,\$numtitles,undef,$cloneruname, - $clonerudom,$typeelement)); + $clonerudom,$typeelement,\@codetitles)); } # ---------------------------------------------------------------- Get the data if ((($env{'form.gosearch'}) && ($env{'form.updater'} eq '')) || $onlyown) { + my $domcloner; + if ($env{'form.form'} eq 'ccrs') { + if (($env{'request.role.domain'} eq $env{'form.domainfilter'}) && + (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'}))) { + $domcloner = 1; + } + } my %courses = &search_courses($r,$type,$onlyown,$filter,$numtitles, - $cloneruname,$clonerudom); + $cloneruname,$clonerudom,$domcloner,\@codetitles); if ($nohost) { $r->print (''. &mt('User does not exist - username: [_1], domain: [_2].', @@ -191,20 +207,19 @@ sub handler { } sub js_changer { - return <<"ENDJS"; + return < - +// ENDJS - } sub processpick { @@ -266,6 +281,13 @@ sub create_user_javascript { my $cdom = $coursedescription{'domain'}; my $cnum = $coursedescription{'num'}; my $crstype = $coursedescription{'type'}; + my %domdefs = &Apache::lonnet::get_domain_defaults($cdom); + my ($showcredits,$credits); + if (($crstype ne 'Community') && + ($domdefs{'officialcredits'} || $domdefs{'unofficialcredits'})) { + $showcredits = 1; + $credits = $coursedescription{'internal.defaultcredits'}; + } my $sec_element = 'currsec'; my $grplist_element = 'groups'; my ($sections,$groups) = @@ -276,6 +298,7 @@ sub create_user_javascript { my $groupslist = join(',',@{$groups}); $output = qq| |; -; } return $output; } @@ -309,9 +341,10 @@ sub display_matched_courses { my $ccrolechk = ' '; my $menuchk = ' checked="checked" '; $r->print( - '
' - .''.&mt('Action').'' - .'
' - .'
' + $r->print('
' + .'' + .'
' ); } } @@ -348,9 +381,9 @@ sub display_matched_courses { } if ($numcourses > 1 && $multiple) { - $r->print('print(' -   

'); } @@ -396,8 +429,16 @@ sub display_matched_courses { $instcode = $courses{$course}{'inst_code'}; $ttype = $courses{$course}{'type'}; if (($env{'form.form'} eq 'ccrs') || ($env{'form.form'} eq 'requestcrs')) { - if ($cc_cloneable{$courses{$course}{'cnum'}.':'.$courses{$course}{'domain'}}) { - $canclone = 1; + if ($env{'form.form'} eq 'ccrs') { + if (($env{'request.role.domain'} eq $cdom) && + (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'}))) { + $canclone = 1; + } + } + unless ($canclone) { + if ($cc_cloneable{$cnum.':'.$cdom}) { + $canclone = 1; + } } unless ($canclone) { my $cloners = $courses{$course}{'cloners'}; @@ -406,7 +447,7 @@ sub display_matched_courses { if (grep(/^\*$/,@cloneable)) { $canclone = 1; } - if (grep(/^\*:\Q$env{'form.clonerudom'}\E$/,@cloneable)) { + if (grep(/^\*:\Q$clonerudom\E$/,@cloneable)) { $canclone = 1; } if (grep(/^\Q$cloneruname\E:\Q$clonerudom\E$/,@cloneable)) { @@ -415,10 +456,10 @@ sub display_matched_courses { } } } - push(@owners,&unescape($courses{$course}{'owner'})); - if (ref($courses{$course}{'co-owners'}) eq 'ARRAY') { - foreach my $item (@{$courses{$course}{'co-owners'}}) { - push(@owners,&unescape($item)); + push(@owners,$courses{$course}{'owner'}); + if ($courses{$course}{'co-owners'} ne '') { + foreach my $item (split(/,/,$courses{$course}{'co-owners'})) { + push(@owners,$item); } } } else { @@ -470,9 +511,9 @@ sub display_matched_courses { } if (!%courses) { - $r->print(&mt('None found')); + $r->print('

'.&mt('None found').'

'); } elsif ($multiple) { - $r->print(''); + $r->print(''); } $r->print(''. "\n".''."\n". @@ -519,7 +560,7 @@ sub multiples_tag { sub build_filters { my ($filterlist,$type,$roleelement,$multelement,$filter,$action, - $numtitlesref,$caller,$cloneruname,$clonerudom,$typeelement) = @_; + $numtitlesref,$caller,$cloneruname,$clonerudom,$typeelement,$codetitlesref) = @_; my ($list,$formname,$fixeddom,$codedom,$jscript); $codedom = $env{'request.role.domain'}; if (defined($env{'form.form'})) { @@ -527,12 +568,10 @@ sub build_filters { } else { $formname = $caller; } - my $onchange; - unless ($env{'form.interface'} eq 'textual') { - $onchange = 'javascript:updateFilters(this)'; - } - my ($domainselectform,$sincefilterform,$ownerdomselectform,$persondomselectform, - $instcodeform,$typeselectform,$instcodetitle); + my $onchange = 'javascript:updateFilters(this)'; + my ($domainselectform,$sincefilterform,$createdfilterform, + $ownerdomselectform,$persondomselectform,$instcodeform, + $typeselectform,$instcodetitle); foreach my $item (@{$filterlist}) { $filter->{$item} = $env{'form.'.$item}; if ($item ne 'descriptfilter' && $item ne 'instcodefilter') { @@ -595,25 +634,16 @@ sub build_filters { } # last course activity filter and selection - $filter->{'sincefilter'} = $env{'form.sincefilter'}; - $filter->{'sincefilter'} =~ s/[^\d-]//g; - if (!$filter->{'sincefilter'}) { $filter->{'sincefilter'}=-1; } - $sincefilterform=&Apache::loncommon::select_form( - $filter->{'sincefilter'}, - 'sincefilter', - ( '-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'])); + $sincefilterform = &timebased_select_form('sincefilter',$filter); + + # course created filter and selection + if (exists($filter->{'createdfilter'})) { + $createdfilterform = &timebased_select_form('createdfilter',$filter); + } my %lt = &Apache::lonlocal::texthash( 'cac' => "$type Activity", + 'ccr' => "$type Created", 'cde' => "$type Title", 'cdo' => "$type Domain", 'ins' => 'Institutional Code', @@ -632,7 +662,7 @@ sub build_filters { } else { $typeselectform = ''; } } - $output .= ''."\n". + $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 (&Apache::lonnet::homeserver($cloneruname,$clonerudom) eq 'no_host') { + if (($cloneruname!~/\w/) || ($clonerudom!~/\w/)) { + my $warning = '
'.&mt('Intended course owner not specified'). + '
'; + return ('',$warning); + } elsif (&Apache::lonnet::homeserver($cloneruname,$clonerudom) eq 'no_host') { my $warning = '
'.&mt('Intended course owner does not exist'). '
'; return ('',$warning); @@ -813,11 +874,11 @@ sub get_coordinator_cloneable { } sub instcode_selectors { - my ($codedom,$formname,$officialjs) = @_; - my ($output,@codetitles,%cat_titles,%cat_order,%cat_items); + my ($codedom,$formname,$officialjs,$codetitles) = @_; + my ($output,%cat_titles,%cat_order,%cat_items); my ($jscript,$totcodes,$numtitles,$lasttitle) = &Apache::courseclassifier::instcode_selectors_data($codedom,$formname, - \%cat_items,\@codetitles,\%cat_titles,\%cat_order,$officialjs); + \%cat_items,$codetitles,\%cat_titles,\%cat_order,$officialjs); if ($numtitles > 0) { my $official = ' checked="checked" '; my $unofficial = ''; @@ -831,7 +892,7 @@ sub instcode_selectors { ''.&mt('No').'
'. &Apache::courseclassifier::build_instcode_selectors($numtitles, - $lasttitle,\%cat_items,\@codetitles,\%cat_titles,\%cat_order)."\n". + $lasttitle,\%cat_items,$codetitles,\%cat_titles,\%cat_order)."\n". ''."\n". ''."\n"; @@ -840,7 +901,7 @@ sub instcode_selectors { } sub search_courses { - my ($r,$type,$onlyown,$filter,$numtitles,$cloneruname,$clonerudom) = @_; + my ($r,$type,$onlyown,$filter,$numtitles,$cloneruname,$clonerudom,$domcloner,$codetitles) = @_; my (%courses,%showcourses,$cloner,$ccrole); if ($type eq 'Community') { $ccrole = 'co'; @@ -848,7 +909,7 @@ sub search_courses { $ccrole = 'cc'; } if (!$onlyown) { - $r->print(&mt('Searching ...').'
 
'); + $r->print('
'.&mt('Searching ...').'
'); $r->rflush(); if (($filter->{'ownerfilter'} ne '') || ($filter->{'ownerdomfilter'} ne '')) { @@ -860,16 +921,22 @@ sub search_courses { $filter->{$item}='.'; } } + my $now = time; my $timefilter = - ($filter->{'sincefilter'}==-1?1:time-$filter->{'sincefilter'}); + ($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); + &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); + $instcodefilter = &Apache::courseclassifier::instcode_search_str($filter->{'domainfilter'},$numtitles,$codetitles); unless ($instcodefilter eq '') { $regexpok = -1; } @@ -892,7 +959,9 @@ sub search_courses { $filter->{'coursefilter'}, undef,undef,$type,$regexpok,undef,undef, undef,undef,$cloner,$env{'form.cc_clone'}, - $filter->{'cloneableonly'}); + $filter->{'cloneableonly'}, + $createdbefore,$createdafter,undef, + $domcloner); if (($filter->{'personfilter'} ne '') && ($filter->{'persondomfilter'} ne '')) { my %rolehash = &Apache::lonnet::get_my_roles($filter->{'personfilter'}, $filter->{'persondomfilter'}, @@ -939,7 +1008,7 @@ sub course_chooser { $output = &mt('No rights to clone')."\n"; } } else { - $output = ''."\n"; } return $output; @@ -959,8 +1028,7 @@ sub gochoose_javascript { list => 'courselist', }, ); - my $output .= qq| - |; - return $output; + return &Apache::lonhtmlcommon::scripttag($output); } 1; @@ -1161,10 +1233,10 @@ Side Effects: None =item * X -B: +B: -Input: 11 - 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, $tyepelem +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. @@ -1172,10 +1244,12 @@ Side Effects: None =item * X -B: +B: -Input: 7 - 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). Last two needed when search is for courses to clone from course request form, or course creation form (DC). +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. @@ -1235,7 +1309,7 @@ javascript functions used when user sele =item -(g) Scantron Operator uploading a scantron file to a course - course number is written to visible form element in opener window. Child window closes. +(g) Bubblesheet Scanning Operator uploading a bubblesheet file to a course - course number is written to visible form element in opener window. Child window closes. =item