--- loncom/interface/coursecatalog.pm 2012/10/04 13:41:10 1.71 +++ loncom/interface/coursecatalog.pm 2013/01/23 15:23:19 1.72 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler for displaying the course catalog interface # -# $Id: coursecatalog.pm,v 1.71 2012/10/04 13:41:10 bisitz Exp $ +# $Id: coursecatalog.pm,v 1.72 2013/01/23 15:23:19 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -92,6 +92,7 @@ sub handler { &course_details($r,$codedom,$formname,$domdesc,\@trails,\%allitems,\@codetitles); } else { my ($catlinks,$has_subcats,$selitem) = &category_breadcrumbs($codedom,@cats); + my $wasacctext = &get_wasactive_text(); my $catjs = <<"ENDSCRIPT"; function setCatDepth(depth) { @@ -114,7 +115,36 @@ function setCourseId(caller) { } ENDSCRIPT - $catjs .= &courselink_javascript(); + $catjs .= &courselink_javascript(); + if (&user_is_dc($codedom)) { + $catjs .= <'."\n"; my $start_page = &Apache::loncommon::start_page('Course/Community Catalog',$js, - {'add_entries' => \%add_entries, }); + {'add_entries' => \%add_entries, }); $r->print($start_page); if ($env{'form.numtitles'} > 0) { &Apache::lonhtmlcommon::add_breadcrumb @@ -266,7 +296,10 @@ sub instcode_course_selector { ''; if ($totcodes) { if (($env{'form.state'} eq 'listing') && ($numtitles > 0)) { - $add_entries{'onLoad'} = 'setElements()'; + $add_entries{'onLoad'} = 'setElements();'; + } + if (&user_is_dc($codedom)) { + $add_entries{'onLoad'} .= ' toggleStatuses();toggleWasActive();' } &cat_header($r,$codedom,$js,\%add_entries,$catlinks,$numtitles); my $cat_maxdepth = $env{'form.catalog_maxdepth'}; @@ -303,7 +336,7 @@ sub instcode_course_selector { sub cat_header { my ($r,$codedom,$js,$add_entries,$catlinks,$numtitles) = @_; my $start_page = - &Apache::loncommon::start_page('Other',$js, + &Apache::loncommon::start_page('Course/Community Catalog',$js, { 'add_entries' => $add_entries, }); $r->print($start_page); my $brtext = 'Course listing'; @@ -492,8 +525,13 @@ sub get_depth_values { sub additional_filters { my ($codedom,$has_subcats) = @_; - my $output = ''; - if (($env{'form.currcat_0'} ne 'instcode::0') && + my $is_dc = &user_is_dc($codedom); + my $output = '
'; + if ($is_dc) { + $output .= '
'.&mt('Options').''; + } + $output .= '
'; + &unescape($catname)).'
'; } } my $show_selfenroll_status; @@ -526,21 +564,34 @@ sub additional_filters { } else { $selfenroll_text = &mt('Only show courses which currently allow self-enrollment (or will allow it in the future)'); } - $output .= ''; - if (&user_is_dc($codedom)) { + '
'; + if ($is_dc) { + my ($titlesref,$orderref) = &get_statustitles('filters'); my $showdetails_status; if ($env{'form.showdetails'}) { $showdetails_status = 'checked="checked" '; } my $showhidden_status; if ($env{'form.showhidden'}) { - $showhidden_status = 'checked="checked" '; + $showhidden_status = 'checked="checked" '; } + my @currstatuses = &Apache::loncommon::get_env_multiple('form.showcounts'); my $dc_title = &Apache::lonnet::plaintext('dc'); - my ($details_text,$hidden_text); + my ($details_text,$hidden_text,$statusdisplay,$cellborder); + my $wasactivedisplay = 'none'; + if ($env{'form.showdetails'}) { + $statusdisplay = 'block'; + $cellborder = 'border-left: 1px solid;'; + if (grep(/^Previous$/,@currstatuses)) { + $wasactivedisplay = 'block'; + } + } else { + $statusdisplay = 'none'; + $cellborder = 'border-left: 0px'; + } if ($env{'form.currcat_0'} eq 'communities::0') { $details_text = &mt('Show full details for each community ([_1] only)',$dc_title); $hidden_text = &mt('Include communities set to be hidden from catalog ([_1] only)',$dc_title); @@ -548,15 +599,100 @@ sub additional_filters { $details_text = &mt('Show full details for each course ([_1] only)',$dc_title); $hidden_text = &mt('Include courses set to be hidden from catalog ([_1] only)',$dc_title); } - $output .= ''; + '
'."\n". + ''. + ''."\n". + ''; + } else { + $output .= ''; } - $output .= '
'; + if (($env{'form.currcat_0'} ne 'instcode::0') && ($env{'form.currcat_0'} ne '') && ($has_subcats)) { my $include_subcat_status; if ($env{'form.withsubcats'}) { @@ -509,11 +547,11 @@ sub additional_filters { } my ($catname) = split(/:/,$env{'form.currcat_'.$counter}); if ($catname ne '') { - $output .= '
'. + $output .= ''. '
'."\n". - ''."\n".'
'. + $output .= ''. ''."\n".'
'. + '
'; + if (ref($orderref) eq 'ARRAY') { + if (@{$orderref} > 0) { + foreach my $type (@{$orderref}) { + my $checked; + if (grep(/^\Q$type\E$/,@currstatuses)) { + $checked = ' checked="checked"'; + } + my $title; + if (ref($titlesref) eq 'HASH') { + $title = $titlesref->{$type}; + } + unless ($title) { + $title = &mt($type); + } + my $onclick; + if ($type eq 'Previous') { + $onclick = ' onclick="toggleWasActive();"'; + } + $output .= ''. + ''; + if ($type eq 'Previous') { + my %milestonetext = &Apache::lonlocal::texthash ( + accessend => 'prior to default end access date', + enrollend => 'prior to end date for auto-enrollment', + date => 'prior to specific date:', + ); + my @statuses = &Apache::loncommon::get_env_multiple('form.showcounts'); + $output .= ''; + if ($checked) { + $output .= &get_wasactive_text(); + } + $output .= ''. + '
'. + ''; + my @milestones = ('accessend'); + if (&Apache::lonnet::auto_run(undef,$codedom)) { + push(@milestones,'enrollend'); + } + push(@milestones,'date'); + foreach my $item (@milestones) { + my $checked; + if ($env{'form.state'} eq 'listing') { + if ($env{'form.wasactive'} eq $item) { + $checked = ' checked="checked"'; + } + } elsif ($item eq 'accessend') { + $checked = ' checked="checked"'; + } + $output .= + ''; + } + $output .= '
 '. + ''; + if ($item eq 'date') { + my $wasactiveon; + if (grep(/^Previous$/,@currstatuses)) { + $wasactiveon = + &Apache::lonhtmlcommon::get_date_from_form('wasactiveon'); + } else { + $wasactiveon = 'now'; + } + $output .= ' '. + &Apache::lonhtmlcommon::date_setter('coursecatalog', + 'wasactiveon', + $wasactiveon, + '','','',1,'', + '','',1); + } + $output .= '
'; + } + $output .= '
'; + } + } + } + $output .= '

'; + $output .= ''. + '
'; return $output; } @@ -573,6 +709,41 @@ sub user_is_dc { return; } +sub get_statustitles { + my ($caller) = @_; + my @status_order = ('Active','Future','Previous'); + my %status_title; + if ($caller eq 'filters') { + %status_title = &Apache::lonlocal::texthash( + Previous => 'Show count for past access', + Active => 'Show count for current student access', + Future => 'Show count for future student access', + ); + if ($env{'form.currcat_0'} eq 'communities::0') { + $status_title{'Active'} = 'Show count for current member access'; + $status_title{'Future'} = 'Show count for future member access'; + } + } else { + %status_title = &Apache::lonlocal::texthash( + Previous => 'Previous access', + Active => 'Current access', + Future => 'Future access', + ); + } + return (\%status_title,\@status_order); +} + +sub get_wasactive_text { + my $wasacctext = ' -- '; + if ($env{'form.currcat_0'} eq 'communities::0') { + $wasacctext .= &mt('where members had access ...'); + } else { + $wasacctext .= &mt('where students had access ...'); + } + $wasacctext .= '
'; + return $wasacctext; +} + sub search_official_courselist { my ($domain,$numtitles,$codetitles) = @_; my $instcode = &Apache::courseclassifier::instcode_search_str($domain,$numtitles,$codetitles); @@ -683,7 +854,8 @@ sub print_course_listing { my $now = time; my %domconfig = &Apache::lonnet::get_dom('configuration',['usercreation'],$domain); - $output .= &construct_data_table($knownuser,\%courses,$details,undef,$now,\%domconfig,$trails,$allitems); + $output .= &construct_data_table($knownuser,$domain,\%courses,$details,undef, + $now,\%domconfig,$trails,$allitems); $output .= "\n".'
'. ''. ''. @@ -692,8 +864,8 @@ sub print_course_listing { } sub construct_data_table { - my ($knownuser,$courses,$details,$usersections,$now,$domconfig,$trails, - $allitems) = @_; + my ($knownuser,$domain,$courses,$details,$usersections,$now,$domconfig, + $trails,$allitems) = @_; my %sortname; if (($details eq '') || ($env{'form.showdetails'})) { $sortname{'Code'} = 'code'; @@ -724,24 +896,60 @@ sub construct_data_table { } $output .= ''; } + my (@fields,%fieldtitles,$wasactiveon); if ($knownuser) { if ($details) { if ($env{'form.currcat_0'} eq 'communities::0') { - $output .= ''.&mt('Default Access Dates for Members').''; + $output .= ''.&mt('Default Access Dates for Members').''. + ''.&mt('Member Counts').''; } else { $output .= ''.&mt('Default Access Dates for Students').''. ''.&mt('Student Counts').''. ''.&mt('Auto-enrollment of[_1]registered students','
').''; } + my ($titlesref,$orderref) = &get_statustitles(); + my @statuses; + if (&user_is_dc($domain)) { + @statuses = &Apache::loncommon::get_env_multiple('form.showcounts'); + if (grep(/^Previous$/,@statuses)) { + if ($env{'form.wasactive'} eq 'date') { + $wasactiveon = + &Apache::lonhtmlcommon::get_date_from_form('wasactiveon'); + } else { + $wasactiveon = $env{'form.wasactive'}; + } + } + if (ref($orderref) eq 'ARRAY') { + foreach my $status (@{$orderref}) { + if (grep(/^\Q$status\E$/,@statuses)) { + push(@fields,$status); + } + } + } + } else { + @fields = ('Active','Future'); + } + foreach my $status (@fields) { + my $title; + if (ref($titlesref) eq 'HASH') { + $title = $titlesref->{$status}; + } + unless ($title) { + $title = &mt($status); + } + $fieldtitles{$status} = $title; + } } else { $output .= ''.&mt('Details').''; } } $output .= ''.&mt('Self-enroll (if permitted)').''; &Apache::loncommon::end_data_table_header_row(); - my %courseinfo = &build_courseinfo_hash($courses,$knownuser,$details, - $usersections); + my %numbers; + my %courseinfo = &build_courseinfo_hash($courses,$knownuser,$domain,$details, + $usersections,\@fields,\%fieldtitles, + $wasactiveon,\%numbers); my %Sortby; foreach my $course (sort(keys(%{$courses}))) { if ($env{'form.sortby'} eq 'code') { @@ -767,22 +975,66 @@ sub construct_data_table { @sorted_courses = sort { lc($a) cmp lc($b) } (keys(%Sortby)); } my $count = 1; + my $totalsec = 0; foreach my $item (@sorted_courses) { foreach my $course (@{$Sortby{$item}}) { $output.=&Apache::loncommon::start_data_table_row(); $output.=&courseinfo_row($courseinfo{$course},$knownuser,$details, - \$count,$now,$course,$trails,$allitems); + \$count,$now,$course,$trails,$allitems,\%numbers); $output.=&Apache::loncommon::end_data_table_row(); } } + if (($knownuser) && ($count > 1) && $env{'form.showdetails'}) { + if (&user_is_dc($domain)) { + my %lt = &Apache::lonlocal::texthash ( + 'Active' => 'Total current students', + 'Future' => 'Total future students', + 'Previous' => 'Total previous students', + 'courses' => 'Total unique codes and courses without codes', + 'sections' => 'Total sections', + 'xlists' => 'Total cross-listings', + ); + if ($env{'form.currcat_0'} eq 'communities::0') { + $lt{'courses'} = &mt('Total communities'); + $lt{'Active'} = &mt('Total current members'); + $lt{'Future'} = &mt('Total future members'); + $lt{'Previous'} = &mt('Total previous members'); + } + $output .= ''. + ' '. + ''. + ''; + foreach my $item ('courses','sections','xlists') { + $output .= ''. + ''. + ''. + ''."\n"; + } + if (@fields > 0) { + foreach my $status (@fields) { + $output .= ''. + ''. + ''. + ''."\n"; + } + } + $output .= '
'.$lt{$item}.''.$numbers{$item}.'
'.$lt{$status}.''.$numbers{$status}.'
'; + } + } $output .= &Apache::loncommon::end_data_table(); return $output; } sub build_courseinfo_hash { - my ($courses,$knownuser,$details,$usersections) = @_; + my ($courses,$knownuser,$domain,$details,$usersections,$fields,$fieldtitles, + $wasactiveon,$numbers) = @_; my %courseinfo; my $now = time; + my $gettotals; + if ((keys(%{$courses}) > 0) && (&user_is_dc($domain)) && ($details)) { + $gettotals = 1; + } + my (%uniquecodes,$nocodes),; foreach my $course (keys(%{$courses})) { my $descr; if (ref($courses->{$course}) eq 'HASH') { @@ -810,6 +1062,11 @@ sub build_courseinfo_hash { } } } + if ($instcode ne '') { + $uniquecodes{$instcode} = 1; + } else { + $nocodes ++; + } foreach my $owner (@owners) { my ($ownername,$ownerdom); if ($owner =~ /:/) { @@ -847,14 +1104,13 @@ sub build_courseinfo_hash { my @crosslistings; my ($seclist,$numsec) = &identify_sections($coursehash{'internal.sectionnums'}); - if (ref($usersections) eq 'HASH') { - if (ref($usersections->{$course}) eq 'ARRAY') { - $seclist = join(', ',@{$usersections->{$course}}); - } - } $courseinfo{$course}{'seclist'} = $seclist; my ($xlist_items,$numxlist) = &identify_sections($coursehash{'internal.crosslistings'}); + if (ref($numbers) eq 'HASH') { + $numbers->{'sections'} += $numsec; + $numbers->{'xlists'} += $numxlist; + } my $showsyllabus = 1; # default is to include a syllabus link if (defined($coursehash{'showsyllabus'})) { $showsyllabus = $coursehash{'showsyllabus'}; @@ -862,11 +1118,30 @@ sub build_courseinfo_hash { $courseinfo{$course}{'showsyllabus'} = $showsyllabus; if (((defined($env{'form.coursenum'}) && ($cnum eq $env{'form.coursenum'}))) || ($knownuser && ($details == 1))) { - $courseinfo{$course}{'counts'} = &count_students($cdom,$cnum,$numsec); - $courseinfo{$course}{'autoenrollment'} = - &autoenroll_info(\%coursehash,$now,$seclist,$xlist_items, - $instcode,\@owners,$cdom,$cnum); - + my $milestone; + if ($wasactiveon eq 'accessend') { + if ($coursehash{'default_enrollment_end_date'}) { + $milestone = $coursehash{'default_enrollment_end_date'}; + } else { + $milestone = time; + } + } elsif ($wasactiveon eq 'enrollend') { + if ($coursehash{'internal.autoend'}) { + $milestone = $coursehash{'internal.autoend'}; + } else { + $milestone = time; + } + } else { + $milestone = $wasactiveon; + } + $courseinfo{$course}{'counts'} = + &count_students($cdom,$cnum,$numsec,$fields,$fieldtitles,$gettotals, + $numbers,$milestone); + if ($instcode ne '') { + $courseinfo{$course}{'autoenrollment'} = + &autoenroll_info(\%coursehash,$now,$seclist,$xlist_items, + $instcode,\@owners,$cdom,$cnum); + } my $startaccess = ''; my $endaccess = ''; my $accessdates; @@ -919,39 +1194,60 @@ sub build_courseinfo_hash { } $courseinfo{$course}{'xlist'} = $xlist_items; } + if (ref($numbers) eq 'HASH') { + $numbers->{'courses'} = $nocodes + scalar(keys(%uniquecodes)); + } return %courseinfo; } sub count_students { - my ($cdom,$cnum,$numsec) = @_; + my ($cdom,$cnum,$numsec,$fieldsref,$titlesref,$getcounts,$numbers,$wasactiveon) = @_; + my $countslist = ''. + &mt('[quant,_1,section,sections,No sections]',$numsec).''; + my (@fields,%titles,$showexpired); + if ((ref($fieldsref) eq 'ARRAY') && (ref($titlesref) eq 'HASH') && + (ref($numbers) eq 'HASH')) { + @fields = @{$fieldsref}; + %titles = %{$titlesref}; + if (grep(/^Previous$/,@fields)) { + $showexpired = 1; + } + } else { + return; + } my $classlist = &Apache::loncoursedata::get_classlist($cdom,$cnum); my %student_count = ( - Active => 0, - Future => 0, - Expired => 0, + Active => 0, + Future => 0, + Previous => 0, ); my %idx; $idx{'status'} = &Apache::loncoursedata::CL_STATUS(); - my %status_title = &Apache::lonlocal::texthash( - Expired => 'Previous access', - Active => 'Current access', - Future => 'Future access', - ); - + $idx{'end'} = &Apache::loncoursedata::CL_END(); while (my ($student,$data) = each(%$classlist)) { - $student_count{$data->[$idx{'status'}]} ++; + my $status = $data->[$idx{'status'}]; + if ($status eq 'Expired') { + if (($showexpired) && + ($data->[$idx{'end'}] >= $wasactiveon)) { + $student_count{'Previous'} ++; + } + } else { + $student_count{$status} ++; + } } - - my $countslist = &mt('[quant,_1,section:,sections:,No sections]',$numsec).'
'; - foreach my $status ('Active','Future') { - $countslist .= ''.$status_title{$status}.': '. - $student_count{$status}.'
'; + if (@fields) { + $countslist .= ':
'; + foreach my $status (@fields) { + $countslist .= ''.$titles{$status}.': '. + $student_count{$status}.'
'; + $numbers->{$status} += $student_count{$status}; + } } return $countslist; } sub courseinfo_row { - my ($info,$knownuser,$details,$countref,$now,$course,$trails,$allitems) = @_; + my ($info,$knownuser,$details,$countref,$now,$course,$trails,$allitems,$numbers) = @_; my ($cdom,$cnum,$title,$ownerlast,$code,$owner,$seclist,$xlist_items, $accessdates,$showsyllabus,$counts,$autoenrollment,$output,$categories); if (ref($info) eq 'HASH') { @@ -1002,13 +1298,11 @@ sub courseinfo_row { ''.$ownerlast.''; if ($knownuser) { if ($details) { - if ($env{'form.currcat_0'} eq 'communities::0') { - $output .= ''.$accessdates.''; - } else { - $output .= - ''.$accessdates.''. - ''.$counts.''. - ''.$autoenrollment.''; + $output .= + ''.$accessdates.''. + ''.$counts.''; + unless ($env{'form.currcat_0'} eq 'communities::0') { + $output .= ''.$autoenrollment.''; } } else { $output .= "".&mt('Show more details').'';