--- loncom/interface/coursecatalog.pm 2008/06/27 04:59:45 1.32 +++ loncom/interface/coursecatalog.pm 2008/07/07 15:20:18 1.36 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler for displaying the course catalog interface # -# $Id: coursecatalog.pm,v 1.32 2008/06/27 04:59:45 raeburn Exp $ +# $Id: coursecatalog.pm,v 1.36 2008/07/07 15:20:18 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -71,19 +71,48 @@ sub handler { } my $domdesc = &Apache::lonnet::domain($codedom,'description'); &Apache::lonhtmlcommon::clear_breadcrumbs(); + + my %domconfig = + &Apache::lonnet::get_dom('configuration',['coursecategories'],$codedom); + my (@cats,@trails,%allitems,%idx,@jsarray,%subcathash,$cathash); + if (ref($domconfig{'coursecategories'}) eq 'HASH') { + $cathash = $domconfig{'coursecategories'}{'cats'}; + } else { + $cathash = {}; + } + my $subcats; + if ($env{'form.withsubcats'}) { + $subcats = \%subcathash; + } + &Apache::loncommon::extract_categories($cathash,\@cats,\@trails,\%allitems, + \%idx,\@jsarray,$subcats); if ($env{'form.coursenum'} ne '' && &user_is_known()) { - &course_details($r,$codedom,$formname,$domdesc); + &course_details($r,$codedom,$formname,$domdesc,\@trails,\%allitems); } else { - my $catlinks = &category_breadcrumbs($codedom); + my ($catlinks,$has_subcats) = &category_breadcrumbs($codedom,@cats); my $catjs = <<"ENDSCRIPT"; function setCatDepth(depth) { document.coursecats.catalog_maxdepth.value = depth; + if (depth == '') { + document.coursecats.currcat_0.value = ''; + } document.coursecats.submit(); return; } ENDSCRIPT + if ($env{'form.state'} eq 'listing') { + $catjs .= qq| +function changeSort(caller) { + document.$formname.sortby.value = caller; + document.$formname.submit(); +} +function setCourseId(caller) { + document.$formname.coursenum.value = caller; + document.$formname.submit(); +}\n|; + } my $numtitles; if ($env{'form.currcat_0'} eq 'instcode::0') { $numtitles = &instcode_course_selector($r,$codedom,$formname,$domdesc, @@ -96,7 +125,25 @@ ENDSCRIPT $catjs = ''; &cat_header($r,$codedom,$catjs,\%add_entries,$catlinks); if ($env{'form.currcat_0'} ne '') { - $r->print(&print_course_listing($codedom)); + $r->print('
'. + &additional_filters($codedom,$has_subcats)."\n"); + my ($currdepth,$deeper) = &get_depth_values(); + $r->print(''."\n"); + for (my $i=0; $i<$deeper; $i++) { + $r->print(''."\n"); + } + $r->print(''."\n". + ''."\n". + ''."\n". + ''. + '


'); + } + if ($env{'form.state'} eq 'listing') { + $r->print(&print_course_listing($codedom,undef,\@trails,\%allitems,$subcats)); } } } @@ -105,7 +152,7 @@ ENDSCRIPT } sub course_details { - my ($r,$codedom,$formname,$domdesc) = @_; + my ($r,$codedom,$formname,$domdesc,$trails,$allitems) = @_; my $output; my %add_entries = (topmargin => "0", marginheight => "0",); @@ -127,7 +174,8 @@ sub course_details { $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course Details')); $r->print('
'.&mt('Detailed course information:').'

'. '
'. - &print_course_listing($codedom).'

'); + &print_course_listing($codedom,undef,$trails,$allitems). + '

'); $r->print(''. &mt('Back to course listing').''. ''."\n$jscript\n$catjs\n". ''; if (($env{'form.state'} eq 'listing') && ($numtitles > 0)) { @@ -268,11 +272,7 @@ function display_courses() { ''."\n". ''."\n". ''. - ''."\n"); - if (&user_is_dc($codedom)) { - $r->print(''."\n". - ''."\n"); - } + &additional_filters($codedom)); if ($numtitles > 0) { $r->print(''.&mt('Choose which course(s) to list.').'
'); $r->print(''); @@ -312,12 +312,14 @@ function display_courses() { } $r->print('
'); } - $r->print(''); - if ($numtitles > 0) { - $r->print(''); - } - $r->print(''); + $r->print(''."\n". + ''."\n". + ''."\n". + ''."\n". + ''. + ''); if (($numtitles > 0) && ($env{'form.state'} eq 'listing')) { $r->print('
'); } @@ -358,61 +360,21 @@ sub cat_header { text=>"Select courses"}); $r->print(&Apache::lonhtmlcommon::breadcrumbs('Select courses')); } - $r->print('
'. - ''. - '
'.&mt('Domain:').''. + $r->print(''. + ''. - ''. - $catlinks.''); - my $show_selfenroll_status; - if ($env{'form.showselfenroll'}) { - $show_selfenroll_status = 'checked="checked" '; - } - if (&user_is_dc($codedom)) { - my $showdetails_status; - if ($env{'form.showdetails'}) { - $showdetails_status = 'checked="checked" '; - } - my $showhidden_status; - if ($env{'form.showhidden'}) { - $showhidden_status = 'checked="checked" '; - } - $r->print(''); - } - $r->print('
'.&mt('Domain:').''. &Apache::loncommon::select_dom_form($codedom,'showdom','',1). - ' 
'. - '

'); + ' 
'. + '
'. + ''.$catlinks.'
'); return; } sub category_breadcrumbs { - my ($dom) = @_; - my %domconfig = - &Apache::lonnet::get_dom('configuration',['coursecategories'],$dom); - my (@cats,@trails,%allitems,%idx,@jsarray,$cathash); - if (ref($domconfig{'coursecategories'}) eq 'HASH') { - $cathash = $domconfig{'coursecategories'}{'cats'}; - } else { - $cathash = {}; - } - &Apache::loncommon::extract_categories($cathash,\@cats,\@trails,\%allitems,\%idx, - \@jsarray); - my $currdepth = 0; - my $deeper = 0; - my $currcat_str; - if ($env{'form.catalog_maxdepth'} ne '') { - $currdepth = $env{'form.catalog_maxdepth'}; - if ($env{'form.currcat_'.$currdepth} eq '') { - $deeper = $currdepth; - } else { - $deeper = $currdepth + 1; - } - } - $currcat_str = ''; + my ($dom,@cats) = @_; + my ($currdepth,$deeper) = &get_depth_values(); + my $currcat_str = ''; my $catlinks = ''.&mt('Catalog:').''; + my $has_subcats; for (my $i=0; $i<$deeper; $i++) { $currcat_str .= ''; my ($cattitle,$shallower); @@ -430,25 +392,22 @@ sub category_breadcrumbs { if (ref($cats[0]) eq 'ARRAY') { if ((@{$cats[0]} == 1) && ($cats[0][0] eq 'instcode')) { $catlinks .= &mt('Official courses (with institutional codes)'). - ''; + ''; $env{'form.currcat_0'} = 'instcode::0'; } else { + $has_subcats = 1; $catlinks .= ''."\n". - ' '; + ' '; } } else { $catlinks .= &mt('Official courses (with institutional codes)'). - ''; + ''; $env{'form.currcat_0'} = 'instcode::0'; } } else { @@ -479,19 +438,95 @@ sub category_breadcrumbs { } $catlinks .= '
'.$currcat; if (ref($cats[$deeper]{$cat}) eq 'ARRAY') { + $has_subcats = 1; + my $selstr; $catlinks .= ': '."\n". - ' '; + ' '; } } $catlinks .= $currcat_str.'
'; - return $catlinks; + return ($catlinks,$has_subcats); +} + +sub get_depth_values { + my $currdepth = 0; + my $deeper = 0; + if ($env{'form.catalog_maxdepth'} ne '') { + $currdepth = $env{'form.catalog_maxdepth'}; + if ($env{'form.currcat_'.$currdepth} eq '') { + $deeper = $currdepth; + } else { + $deeper = $currdepth + 1; + } + } + return ($currdepth,$deeper); +} + +sub additional_filters { + my ($codedom,$has_subcats) = @_; + my $output = ''; + if (($env{'form.currcat_0'} ne 'instcode::0') && + ($env{'form.currcat_0'} ne '') && ($has_subcats)) { + my $include_subcat_status; + if ($env{'form.withsubcats'}) { + $include_subcat_status = 'checked="checked" '; + } + my $counter = $env{'form.catalog_maxdepth'}; + if ($counter > 0) { + if ($env{'form.state'} eq 'listing') { + $counter --; + } elsif ($env{'form.currcat_'.$counter} eq '') { + $counter --; + } + } + my ($catname) = split(/:/,$env{'form.currcat_'.$counter}); + if ($catname ne '') { + $output .= ''; + } + } + my $show_selfenroll_status; + if ($env{'form.showselfenroll'}) { + $show_selfenroll_status = 'checked="checked" '; + } + $output .= ''; + if (&user_is_dc($codedom)) { + my $showdetails_status; + if ($env{'form.showdetails'}) { + $showdetails_status = 'checked="checked" '; + } + my $showhidden_status; + if ($env{'form.showhidden'}) { + $showhidden_status = 'checked="checked" '; + } + my $dc_title = &Apache::lonnet::plaintext('dc'); + $output .= ''; + } + $output .= '
'. + '
'."\n". + ''."\n".'
'. + ''."\n".'

'; + return $output; } sub user_is_dc { @@ -626,7 +661,7 @@ sub search_official_courselist { } sub search_courselist { - my ($domain) = @_; + my ($domain,$subcats) = @_; my $cat_maxdepth = $env{'form.catalog_maxdepth'}; my $filter = $env{'form.currcat_'.$cat_maxdepth}; if (($filter eq '') && ($cat_maxdepth > 0)) { @@ -634,7 +669,24 @@ sub search_courselist { $filter = $env{'form.currcat_'.$shallower}; } my %courses; + my $filterstr; if ($filter ne '') { + if ($env{'form.withsubcats'}) { + if (ref($subcats) eq 'HASH') { + if (ref($subcats->{$filter}) eq 'ARRAY') { + $filterstr = join('&',@{$subcats->{$filter}}); + if ($filterstr ne '') { + $filterstr = $filter.'&'.$filterstr; + } + } else { + $filterstr = $filter; + } + } else { + $filterstr = $filter; + } + } else { + $filterstr = $filter; + } my $showhidden; if (&user_is_dc($domain)) { $showhidden = $env{'form.showhidden'}; @@ -642,13 +694,13 @@ sub search_courselist { %courses = &Apache::lonnet::courseiddump($domain,'.',1,'.','.','.',undef,undef, '.',1,$env{'form.showselfenroll'}, - $filter,$showhidden,'coursecatalog'); + $filterstr,$showhidden,'coursecatalog'); } return %courses; } sub print_course_listing { - my ($domain,$numtitles) = @_; + my ($domain,$numtitles,$trails,$allitems,$subcats) = @_; my $output; my %courses; my $knownuser = &user_is_known(); @@ -661,7 +713,7 @@ sub print_course_listing { if ($env{'form.coursenum'} ne '') { %courses = &Apache::lonnet::courseiddump($domain,'.',1,'.','.', $env{'form.coursenum'}, - undef,undef,'Course',1); + undef,undef,'.',1); if (keys(%courses) == 0) { $output .= &mt('The courseID provided does not match a course in this domain.'); return $output; @@ -670,7 +722,7 @@ sub print_course_listing { if ($env{'form.currcat_0'} eq 'instcode::0') { %courses = &search_official_courselist($domain,$numtitles); } else { - %courses = &search_courselist($domain); + %courses = &search_courselist($domain,$subcats); } if (keys(%courses) == 0) { $output = &mt('No courses match the criteria you selected.'); @@ -685,22 +737,32 @@ 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); - $output .= &Apache::lonhtmlcommon::echo_form_input(['coursenum','state','catalogfilter','sortby','showdetails']); + $output .= &construct_data_table($knownuser,\%courses,$details,undef,$now,\%domconfig,$trails,$allitems); + if ($env{'form.coursenum'} ne '') { + $output .= &Apache::lonhtmlcommon::echo_form_input(['coursenum','state','catalogfilter','sortby','showdetails']); + } return $output; } sub construct_data_table { - my ($knownuser,$courses,$details,$usersections,$now,$domconfig) = @_; + my ($knownuser,$courses,$details,$usersections,$now,$domconfig,$trails, + $allitems) = @_; my %sortname; if (($details eq '') || ($env{'form.showdetails'})) { $sortname{'Code'} = 'code'; + $sortname{'Categories'} = 'cats'; $sortname{'Title'} = 'title'; $sortname{'Owner(s)'} = 'owner'; } my $output = &Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row(); - my @coltitles = ('Count','Code','Sections','Crosslisted','Title','Owner(s)'); + my @coltitles = ('Count'); + if ($env{'form.currcat_0'} eq 'instcode::0') { + push(@coltitles,'Code'); + } else { + push(@coltitles,'Categories'); + } + push(@coltitles,('Sections','Crosslisted','Title','Owner(s)')); if (ref($usersections) eq 'HASH') { $coltitles[1] = 'Your Section'; } @@ -733,6 +795,8 @@ sub construct_data_table { foreach my $course (sort(keys(%{$courses}))) { if ($env{'form.sortby'} eq 'code') { push(@{$Sortby{$courseinfo{$course}{'code'}}},$course); + } elsif ($env{'form.sortby'} eq 'cats') { + push(@{$Sortby{$courseinfo{$course}{'categories'}}},$course); } elsif ($env{'form.sortby'} eq 'owner') { push(@{$Sortby{$courseinfo{$course}{'ownerlastnames'}}},$course); } else { @@ -745,7 +809,8 @@ sub construct_data_table { } } my @sorted_courses; - if (($env{'form.sortby'} eq 'code') || ($env{'form.sortby'} eq 'owner')) { + if (($env{'form.sortby'} eq 'code') || ($env{'form.sortby'} eq 'owner') || + ($env{'form.sortby'} eq 'cats')) { @sorted_courses = sort(keys(%Sortby)); } else { @sorted_courses = sort { lc($a) cmp lc($b) } (keys(%Sortby)); @@ -754,8 +819,8 @@ sub construct_data_table { 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); + $output.=&courseinfo_row($courseinfo{$course},$knownuser,$details, + \$count,$now,$course,$trails,$allitems); $output.=&Apache::loncommon::end_data_table_row(); } } @@ -777,7 +842,7 @@ sub build_courseinfo_hash { $cleandesc =~ s/^\s+//; my ($cdom,$cnum)=split(/\_/,$course); my ($descr,$instcode,$singleowner,$ttype,$selfenroll_types, - $selfenroll_start,$selfenroll_end,@owners,%ownernames); + $selfenroll_start,$selfenroll_end,@owners,%ownernames,$categories); if (ref($courses->{$course}) eq 'HASH') { $descr = $courses->{$course}{'description'}; $instcode = $courses->{$course}{'inst_code'}; @@ -786,6 +851,7 @@ sub build_courseinfo_hash { $selfenroll_types = $courses->{$course}{'selfenroll_types'}; $selfenroll_start = $courses->{$course}{'selfenroll_start_date'}; $selfenroll_end = $courses->{$course}{'selfenroll_end_date'}; + $categories = $courses->{$course}{'categories'}; push(@owners,$singleowner); if (ref($courses->{$course}{'co-owners'}) eq 'ARRAY') { foreach my $item (@{$courses->{$course}{'co-owners'}}) { @@ -823,6 +889,7 @@ sub build_courseinfo_hash { $courseinfo{$course}{'selfenroll_types'} = $selfenroll_types; $courseinfo{$course}{'selfenroll_start'} = $selfenroll_start; $courseinfo{$course}{'selfenroll_end'} = $selfenroll_end; + $courseinfo{$course}{'categories'} = $categories; my %coursehash = &Apache::lonnet::dump('environment',$cdom,$cnum); my @classids; @@ -858,7 +925,7 @@ sub build_courseinfo_hash { if ( defined($coursehash{'default_enrollment_end_date'}) ) { $endaccess = &Apache::lonlocal::locallocaltime($coursehash{'default_enrollment_end_date'}); if ($coursehash{'default_enrollment_end_date'} == 0) { - $endaccess = "No ending date"; + $endaccess = &mt('No ending date'); } } if ($startaccess) { @@ -867,6 +934,33 @@ sub build_courseinfo_hash { if ($endaccess) { $accessdates .= &mt('To: ').$endaccess.'
'; } + if (($selfenroll_types ne '') && + ($selfenroll_end > 0 && $selfenroll_end > $now)) { + my ($selfenroll_start_access,$selfenroll_end_access); + if (($coursehash{'default_enrollment_start_date'} ne + $coursehash{'internal.selfenroll_start_access'}) || + ($coursehash{'default_enrollment_end_date'} ne + $coursehash{'internal.selfenroll_end_access'})) { + if ( defined($coursehash{'internal.selfenroll_start_access'}) ) { + $selfenroll_start_access = &Apache::lonlocal::locallocaltime($coursehash{'internal.selfenroll_start_access'}); + } + if ( defined($coursehash{'default_enrollment_end_date'}) ) { + $selfenroll_end_access = &Apache::lonlocal::locallocaltime($coursehash{'internal.selfenroll_end_access'}); + if ($coursehash{'internal.selfenroll_end_access'} == 0) { + $selfenroll_end_access = &mt('No ending date'); + } + } + if ($selfenroll_start_access || $selfenroll_end_access) { + $accessdates .= '

'.&mt('Self-enrollers:').'
'; + if ($selfenroll_start_access) { + $accessdates .= &mt('From: ').$selfenroll_start_access.'
'; + } + if ($selfenroll_end_access) { + $accessdates .= &mt('To: ').$selfenroll_end_access.'
'; + } + } + } + } $courseinfo{$course}{'access'} = $accessdates; } if ($xlist_items eq '') { @@ -906,9 +1000,9 @@ sub count_students { } sub courseinfo_row { - my ($info,$knownuser,$details,$countref,$now,$course) = @_; + my ($info,$knownuser,$details,$countref,$now,$course,$trails,$allitems) = @_; my ($cdom,$cnum,$title,$ownerlast,$code,$owner,$seclist,$xlist_items, - $accessdates,$showsyllabus,$counts,$autoenrollment,$output); + $accessdates,$showsyllabus,$counts,$autoenrollment,$output,$categories); if (ref($info) eq 'HASH') { $cdom = $info->{'cdom'}; $cnum = $info->{'cnum'}; @@ -922,14 +1016,30 @@ sub courseinfo_row { $counts = $info->{'counts'}; $autoenrollment = $info->{'autoenrollment'}; $showsyllabus = $info->{'showsyllabus'}; + $categories = $info->{'categories'}; } else { $output = ''.&mt('No information available for [_1].', $code).''; return $output; } - $output .= ''.$$countref.''. - ''.$code.''. - ''.$seclist.''. + $output .= ''.$$countref.''; + if ($env{'form.currcat_0'} eq 'instcode::0') { + $output .= ''.$code.''; + } else { + my ($categorylist,@cats); + if ($categories ne '') { + @cats = split('&',$categories); + } + if ((ref($trails) eq 'ARRAY') && (ref($allitems) eq 'HASH')) { + my @categories = map { $trails->[$allitems->{$_}]; } @cats; + $categorylist = join('
',@categories); + } + if ($categorylist eq '') { + $categorylist = ' '; + } + $output .= ''.$categorylist.''; + } + $output .= ''.$seclist.''. ''.$xlist_items.''. ''.$title.' '; if ($showsyllabus) {