--- loncom/interface/lonpickcourse.pm 2009/11/04 14:12:19 1.90 +++ loncom/interface/lonpickcourse.pm 2010/06/25 04:37:49 1.98 @@ -1,7 +1,7 @@ # The LearningOnline Network # Pick a course # -# $Id: lonpickcourse.pm,v 1.90 2009/11/04 14:12:19 raeburn Exp $ +# $Id: lonpickcourse.pm,v 1.98 2010/06/25 04:37:49 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -79,7 +79,7 @@ sub handler { $typeelement = ''; } - # if called when a DC is creating a course + # 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)$/); } @@ -142,8 +142,17 @@ sub handler { my $action = '/adm/pickcourse'; my ($numtitles,$showroles,$nohost); 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 '')) { @@ -174,8 +183,15 @@ sub handler { # ---------------------------------------------------------------- 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); if ($nohost) { $r->print (''. &mt('User does not exist - username: [_1], domain: [_2].', @@ -306,12 +322,8 @@ sub display_matched_courses { } my $cctitle = &Apache::lonnet::plaintext($ccrole,$type); my $dctitle = &Apache::lonnet::plaintext('dc'); - my $ccrolechk = ' checked="checked" '; - my $menuchk = ' '; - if ($env{'form.prevphase'} ne '') { - $ccrolechk = ' '; - $menuchk = ' checked="checked" '; - } + my $ccrolechk = ' '; + my $menuchk = ' checked="checked" '; $r->print( '
' .''.&mt('Action').'' @@ -380,6 +392,14 @@ sub display_matched_courses { } $r->print(&Apache::loncommon::end_data_table_header_row()); } + my %cc_cloneable; + if (($env{'form.form'} eq 'ccrs') || ($env{'form.form'} eq 'requestcrs')) { + my ($coord_cloneable,$warning) = + &get_coordinator_cloneable($cloneruname,$clonerudom,$type); + if ($coord_cloneable) { + map {$cc_cloneable{$_} = 1;} split('&',$coord_cloneable); + } + } foreach my $description (sort { lc($a) cmp lc($b) } (keys(%by_descrip))) { foreach my $course (@{$by_descrip{$description}}) { $r->print(&Apache::loncommon::start_data_table_row()); @@ -392,17 +412,30 @@ sub display_matched_courses { $instcode = $courses{$course}{'inst_code'}; $ttype = $courses{$course}{'type'}; if (($env{'form.form'} eq 'ccrs') || ($env{'form.form'} eq 'requestcrs')) { - my $cloners = $courses{$course}{'cloners'}; - if ($cloners ne '') { - my @cloneable = split(',',$cloners); - if (grep(/^\*$/,@cloneable)) { + if ($env{'form.form'} eq 'ccrs') { + if (($env{'request.role.domain'} eq $cdom) && + (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'}))) { $canclone = 1; } - if (grep(/^\*:\Q$env{'form.clonerudom'}\E$/,@cloneable)) { + } + unless ($canclone) { + if ($cc_cloneable{$cnum.':'.$cdom}) { $canclone = 1; } - if (grep(/^\Q$cloneruname\E:\Q$clonerudom\E$/,@cloneable)) { - $canclone = 1; + } + unless ($canclone) { + my $cloners = $courses{$course}{'cloners'}; + if ($cloners ne '') { + my @cloneable = split(',',$cloners); + if (grep(/^\*$/,@cloneable)) { + $canclone = 1; + } + if (grep(/^\*:\Q$clonerudom\E$/,@cloneable)) { + $canclone = 1; + } + if (grep(/^\Q$cloneruname\E:\Q$clonerudom\E$/,@cloneable)) { + $canclone = 1; + } } } } @@ -417,7 +450,7 @@ sub display_matched_courses { ($descr,$instcode,$singleowner,$ttype)=split(/:/,$courses{$course}); push(@owners,&unescape($singleowner)); } - my $ownerstr = join(', ',@owners); + my $ownerstr = join(', ',map { &Apache::loncommon::plainname(split(':',$_)); } @owners); $r->print(''.&course_chooser($multiple,$cdom,$cnum,$cleandesc,$canclone).''); $r->print(''.$description.''); $r->print(''); @@ -518,12 +551,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') { @@ -586,30 +617,23 @@ 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' => 'today', - '604800' => 'last week', - '2592000' => 'last month', - '7776000' => 'last three months', - '15552000' => 'last six months', - '31104000' => 'last year', - 'select_form_order' => - ['-1','86400','604800','2592000','7776000', - '15552000','31104000'])); - - my %lt = ( - 'cac' => &mt("$type Activity"), - 'cde' => &mt("$type Title"), - 'cdo' => &mt("$type Domain"), - 'ins' => &mt('Institutional Code'), - 'inc' => &mt('Institutional Categorization'), - 'cow' => &mt("$type Owner/Co-owner"), - 'cop' => &mt("$type Personnel Includes"), - 'cog' => &mt('Type') + $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', + 'inc' => 'Institutional Categorization', + 'cow' => "$type Owner/Co-owner", + 'cop' => "$type Personnel Includes", + 'cog' => 'Type', ); if (($env{'form.form'} eq 'ccrs') || ($env{'form.form'} eq 'requestcrs')) { @@ -708,6 +732,11 @@ $typeelement .$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 @@ -760,33 +789,15 @@ $typeelement .&Apache::lonhtmlcommon::row_closure(1); } $output .= &Apache::lonhtmlcommon::end_pick_box().'

'; - my $warning; + my ($coord_cloneable,$warning); if (($env{'form.form'} eq 'ccrs') || ($env{'form.form'} eq 'requestcrs')) { - my $cloneruhome=&Apache::lonnet::homeserver($cloneruname,$clonerudom); - my $cc_clone; - if ($cloneruhome eq 'no_host') { - $warning = '

'.&mt('Intended course owner does not exist'). - '
'; - } else { - my $ccrole; - if ($type eq 'Community') { - $ccrole = 'co'; - } elsif ($type eq 'Course') { - $ccrole = 'cc'; - } - if ($env{'form.form'} eq 'ccrs') { - $output .= ''."\n"; - } - my %ccroles = &Apache::lonnet::get_my_roles($cloneruname,$clonerudom, - 'userroles',['active'], [$ccrole]); - foreach my $key (sort(keys(%ccroles))) { - my ($cnum,$cdom,$role) = split(':',$key); - $cc_clone .= $cdom.':'.$cnum.'&'; - } - $cc_clone =~ s/\&$//; + ($coord_cloneable,$warning) = + &get_coordinator_cloneable($cloneruname,$clonerudom,$type); + if ($env{'form.form'} eq 'ccrs') { + $output .= ''."\n"; } - if ($cc_clone ne '') { - $output .= ''; + if ($coord_cloneable) { + $output .= ''; } } $output .= ''."\n". @@ -795,6 +806,52 @@ $typeelement 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') { + my $warning = '
'.&mt('Intended course owner does not exist'). + '
'; + return ('',$warning); + } else { + my ($cc_clone,$ccrole); + if ($type eq 'Community') { + $ccrole = 'co'; + } elsif ($type eq 'Course') { + $ccrole = 'cc'; + } + my %ccroles = &Apache::lonnet::get_my_roles($cloneruname,$clonerudom, + 'userroles',['active'], [$ccrole]); + foreach my $key (sort(keys(%ccroles))) { + my ($cnum,$cdom,$role) = split(':',$key); + $cc_clone .= $cdom.':'.$cnum.'&'; + } + $cc_clone =~ s/\&$//; + return ($cc_clone); + } +} + sub instcode_selectors { my ($codedom,$formname,$officialjs) = @_; my ($output,@codetitles,%cat_titles,%cat_order,%cat_items); @@ -823,7 +880,7 @@ sub instcode_selectors { } sub search_courses { - my ($r,$type,$onlyown,$filter,$numtitles,$cloneruname,$clonerudom) = @_; + my ($r,$type,$onlyown,$filter,$numtitles,$cloneruname,$clonerudom,$domcloner) = @_; my (%courses,%showcourses,$cloner,$ccrole); if ($type eq 'Community') { $ccrole = 'co'; @@ -843,8 +900,14 @@ 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') { @@ -875,7 +938,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'}, @@ -1155,10 +1220,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: 8 - 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). Optional "domcloner" flag (has value=1 if user has ccc priv in +domain being filtered by (used when DC is using course creation form). Output: 1 - %courses - hash of courses satisfying search criteria, keys = course IDs, values are corresponding colon-separated escaped description, institutional code, owner and type.