--- loncom/interface/coursecatalog.pm 2013/01/23 15:23:19 1.72 +++ loncom/interface/coursecatalog.pm 2014/04/28 22:12:55 1.84 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler for displaying the course catalog interface # -# $Id: coursecatalog.pm,v 1.72 2013/01/23 15:23:19 raeburn Exp $ +# $Id: coursecatalog.pm,v 1.84 2014/04/28 22:12:55 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -66,8 +66,11 @@ sub handler { } my $formname = 'coursecatalog'; if ($env{'form.showdom'} ne '') { + $env{'form.showdom'} = &LONCAPA::clean_domain($env{'form.showdom'}); if (&Apache::lonnet::domain($env{'form.showdom'}) ne '') { $codedom = $env{'form.showdom'}; + } else { + $env{'form.showdom'} = ''; } } my $domdesc = &Apache::lonnet::domain($codedom,'description'); @@ -75,20 +78,147 @@ sub handler { my %domconfig = &Apache::lonnet::get_dom('configuration',['coursecategories'],$codedom); - my (@cats,@trails,%allitems,%idx,@jsarray,%subcathash,$cathash); + my $knownuser = &user_is_known(); + + my ($cathash,$cattype); if (ref($domconfig{'coursecategories'}) eq 'HASH') { $cathash = $domconfig{'coursecategories'}{'cats'}; + if ($knownuser) { + $cattype = $domconfig{'coursecategories'}{'auth'}; + } else { + $cattype = $domconfig{'coursecategories'}{'unauth'}; + } } else { $cathash = {}; + $cattype = 'std'; + } + if ($cattype eq 'none') { + $r->print(&Apache::loncommon::start_page('Course/Community Catalog')); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"/adm/coursecatalog", + text=>"Course/Community Catalog"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course/Community Catalog')); + if ($knownuser) { + $r->print('
'.&mt('No catalog of LON-CAPA courses/communities is provided for: [_1]',$domdesc).'
'); + } else { + if ($domconfig{'coursecategories'}{'auth'} eq 'none') { + $r->print('
'.&mt('No catalog of LON-CAPA courses/communities is provided for: [_1]',$domdesc).'
'); + } else { + $r->print('
'.&mt('The catalog of LON-CAPA courses/communities provided for: "[_1]" is only available to users who are logged in.',$domdesc).'
'); + } + } + $r->print(&Apache::loncommon::end_page()); + return OK; + } + + my $cnum; + if ($cattype eq 'codesrch') { + my ($uniquecode,$codemsg,$brtext); + if ($env{'form.uniquecode'}) { + $uniquecode = $env{'form.uniquecode'}; + $uniquecode =~ s/^\s+|\s+$//g; + } + my $js = ''."\n"; + $r->print(&Apache::loncommon::start_page('Search for a Course/Community',$js)); + if ($uniquecode =~ /^\w{6}$/) { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"/adm/coursecatalog", + text=>"Course/Community Catalog"}); + $brtext = 'Search Result'; + } else { + $brtext = 'Course/Community Catalog'; + } + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"/adm/coursecatalog", + text=>"$brtext"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course/Community Catalog')); + $r->print(&coursesearch($codedom,$domdesc,$uniquecode)); + if ($uniquecode =~ /^\w{6}$/) { + $r->print('
'); + my $confname = $codedom.'-domainconfig'; + my %codes = &Apache::lonnet::get('uniquecodes',[$uniquecode],$codedom,$confname); + if ($codes{$uniquecode}) { + $cnum = $codes{$uniquecode}; + my %courses = &Apache::lonnet::courseiddump($codedom,'.',1,'.','.', + $cnum,undef,undef,'.',1); + if (keys(%courses)) { + $env{'form.coursenum'} = $cnum; + my %courseinfo = &build_courseinfo_hash(\%courses,$knownuser,$codedom); + undef($env{'form.coursenum'}); + if (ref($courseinfo{$codedom.'_'.$cnum}) eq 'HASH') { + $r->print(&Apache::lonhtmlcommon::start_pick_box()); + my @cols = ('title','ownerlastnames','seclist','access'); + my %lt = &Apache::lonlocal::texthash( + title => 'Title', + ownerlastnames => 'Owner & Co-owner(s)', + seclist => 'Sections', + access => 'Default Access Dates for Students', + ); + my @shown; + foreach my $item (@cols) { + if ($courseinfo{$codedom.'_'.$cnum}{$item}) { + push(@shown,$item); + } + } + my $num = 0; + foreach my $item (@shown) { + $num ++; + $r->print(&Apache::lonhtmlcommon::row_title($lt{$item}). + $courseinfo{$codedom.'_'.$cnum}{$item}); + if ($item eq 'title') { + if ($courseinfo{$codedom.'_'.$cnum}{'showsyllabus'}) { + $r->print(' '. + ''. + &mt('Syllabus').''); + } + } + my $arg = ( $num == scalar(@shown) ? 1 : '' ); + $r->print(&Apache::lonhtmlcommon::row_closure($arg)); + } + $r->print(&Apache::lonhtmlcommon::end_pick_box()); + my $selfenroll = &selfenroll_status($courseinfo{$codedom.'_'.$cnum},$codedom.'_'.$cnum); + if ($selfenroll) { + $r->print('
'.$selfenroll); + } + $r->print('
'."\n". + ''."\n". + ''."\n". + '
'."\n"); + + } else { + $codemsg = &mt('Code matched, but course ID to which this mapped is invalid.'); + } + } else { + $codemsg = &mt('Code matched, but course ID to which this mapped is invalid.'); + } + } else { + $codemsg = &mt('No match'); + } + } + $r->print('
'.&Apache::loncommon::end_page()); + return OK; + } else { + if ($env{'form.coursenum'}) { + $cnum = $env{'form.coursenum'}; + } + } + + if ($env{'form.catalog_maxdepth'} ne '') { + $env{'form.catalog_maxdepth'} =~ s{\D}{}g; } - my $subcats; + + my (@cats,@trails,%allitems,%idx,@jsarray,%subcathash,$subcats); if ($env{'form.withsubcats'}) { $subcats = \%subcathash; } &Apache::loncommon::extract_categories($cathash,\@cats,\@trails,\%allitems, \%idx,\@jsarray,$subcats); my ($numtitles,@codetitles); - if ($env{'form.coursenum'} ne '' && &user_is_known()) { + if (($env{'form.coursenum'} ne '') && ($knownuser)) { &course_details($r,$codedom,$formname,$domdesc,\@trails,\%allitems,\@codetitles); } else { my ($catlinks,$has_subcats,$selitem) = &category_breadcrumbs($codedom,@cats); @@ -147,7 +277,7 @@ ENDTOGGJS } if ($env{'form.currcat_0'} eq 'instcode::0') { $numtitles = &instcode_course_selector($r,$codedom,$formname,$domdesc, - $catlinks,$catjs,\@codetitles); + $catlinks,$catjs,\@codetitles,$cattype); if ($env{'form.state'} eq 'listing') { $r->print(&print_course_listing($codedom,$numtitles,undef,undef,undef, \@codetitles)); @@ -170,7 +300,7 @@ function check_selected() { ENDJS } $catjs = ''; - &cat_header($r,$codedom,$catjs,\%add_entries,$catlinks); + &cat_header($r,$codedom,$catjs,\%add_entries,$catlinks,undef,$cattype); if ($env{'form.currcat_0'} ne '') { $r->print('
'. @@ -229,29 +359,48 @@ sub course_details { ({href=>"javascript:document.$formname.submit()", text=>$brtextone}, {text=>$brtexttwo}); - $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course/Community Catalog')); - $r->print('
'); - if ($env{'form.currcat_0'} eq 'communities::0') { - $r->print(&mt('Detailed community information:')); - } else { - $r->print(&mt('Detailed course information:')); - } - $r->print('

'. - &print_course_listing($codedom,undef,$trails,$allitems,undef,$codetitles). - '

'); - $r->print(''. - ''); - if ($env{'form.currcat_0'} eq 'communities::0') { - $r->print(&mt('Back to community listing')); - } else { - $r->print(&mt('Back to course listing')); - } - $r->print(''. - &Apache::lonhtmlcommon::echo_form_input(['coursenum','catalogfilter', - 'showdetails','courseid']).'
'); + $r->print( + &Apache::lonhtmlcommon::breadcrumbs('Course/Community Catalog'). + '

'. + (($env{'form.currcat_0'} eq 'communities::0') ? + &mt('Detailed community information:') : + &mt('Detailed course information:')). + '

'. + &print_course_listing($codedom,undef,$trails,$allitems,undef,$codetitles). + '
'. + '
'. + &Apache::lonhtmlcommon::actionbox([ + ''. + (($env{'form.currcat_0'} eq 'communities::0') ? + &mt('Back to community listing') : &mt('Back to course listing')). + '' + ]). + &Apache::lonhtmlcommon::echo_form_input(['coursenum','catalogfilter', + 'showdetails','courseid']). + '
'); return; } +sub coursesearch { + my ($codedom,$domdesc,$uniquecode) = @_; + my %lt = &Apache::lonlocal::texthash ( + crlk => 'Course look-up', + code => 'Code', + ifyo => 'Enter the course code (six letters and numbers)', + srch => 'Find course', + ); + return <<"END"; +

$lt{'crlk'} ($domdesc)

+$lt{'ifyo'} +
+ +  +
+
+
+END +} + sub courselink_javascript { return <<"END"; @@ -279,7 +428,7 @@ END } sub instcode_course_selector { - my ($r,$codedom,$formname,$domdesc,$catlinks,$catjs,$codetitles) = @_; + my ($r,$codedom,$formname,$domdesc,$catlinks,$catjs,$codetitles,$cattype) = @_; my %coursecodes = (); my %codes = (); my %cat_titles = (); @@ -292,8 +441,11 @@ sub instcode_course_selector { my ($jscript,$totcodes,$numtitles,$lasttitle) = &Apache::courseclassifier::instcode_selectors_data($codedom,$formname, \%cat_items,$codetitles,\%cat_titles,\%cat_order); - my $js = ''; + my $js = ''; if ($totcodes) { if (($env{'form.state'} eq 'listing') && ($numtitles > 0)) { $add_entries{'onLoad'} = 'setElements();'; @@ -301,7 +453,7 @@ sub instcode_course_selector { if (&user_is_dc($codedom)) { $add_entries{'onLoad'} .= ' toggleStatuses();toggleWasActive();' } - &cat_header($r,$codedom,$js,\%add_entries,$catlinks,$numtitles); + &cat_header($r,$codedom,$js,\%add_entries,$catlinks,$numtitles,$cattype); my $cat_maxdepth = $env{'form.catalog_maxdepth'}; $r->print('
'. ''."\n". @@ -321,8 +473,12 @@ sub instcode_course_selector { '


'); } else { - $js = ''; - &cat_header($r,$codedom,$js,\%add_entries,$catlinks,$numtitles); + $js = ''; + &cat_header($r,$codedom,$js,\%add_entries,$catlinks,$numtitles,$cattype); my $cat_maxdepth = $env{'form.catalog_maxdepth'}; $r->print('
'. ''. @@ -334,7 +490,7 @@ sub instcode_course_selector { } sub cat_header { - my ($r,$codedom,$js,$add_entries,$catlinks,$numtitles) = @_; + my ($r,$codedom,$js,$add_entries,$catlinks,$numtitles,$cattype) = @_; my $start_page = &Apache::loncommon::start_page('Course/Community Catalog',$js, { 'add_entries' => $add_entries, }); @@ -359,15 +515,17 @@ sub cat_header { text=>"Course/Community Catalog"}); } $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course/Community Catalog')); - my $onchange = 'this.form.submit()'; - $r->print(''. - '
'.&mt('Domain:').''. - &Apache::loncommon::select_dom_form($codedom,'showdom','',1,$onchange)); - if (!$onchange) { + if ($cattype eq 'std') { + my $onchange = 'this.form.submit()'; + $r->print(''. + '
'.&mt('Domain:').''. + &Apache::loncommon::select_dom_form($codedom,'showdom','',1,$onchange)); + if (!$onchange) { $r->print(' '); + } + $r->print('
'); } - $r->print('
'. - '
print(''. ''.$catlinks.'
'); return; @@ -405,8 +563,6 @@ sub category_breadcrumbs { if (($env{'form.currcat_0'} ne '') && ($env{'form.currcat_0'} ne 'instcode::0')) { $catlinks .= $crumbsymbol; - } else { - $catlinks .= ''; } } } else { @@ -633,12 +789,12 @@ sub additional_filters { ' />'.$title.''; 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:', + accessend => 'immediately prior to default end access date', + enrollend => 'immediately prior to end date for auto-enrollment', + date => 'immediately prior to specific date:', ); my @statuses = &Apache::loncommon::get_env_multiple('form.showcounts'); - $output .= ''; + $output .= ''; if ($checked) { $output .= &get_wasactive_text(); } @@ -736,11 +892,10 @@ sub get_statustitles { sub get_wasactive_text { my $wasacctext = ' -- '; if ($env{'form.currcat_0'} eq 'communities::0') { - $wasacctext .= &mt('where members had access ...'); + $wasacctext .= &mt('where member access status was current ...'); } else { - $wasacctext .= &mt('where students had access ...'); + $wasacctext .= &mt('where student access status was current ...'); } - $wasacctext .= '
'; return $wasacctext; } @@ -818,11 +973,13 @@ sub print_course_listing { $env{'form.coursenum'}, undef,undef,'.',1); if (keys(%courses) == 0) { + $output = '

'; if ($env{'form.currcat_0'} eq 'communities::0') { $output .= &mt('The courseID provided does not match a community in this domain.'); } else { $output .= &mt('The courseID provided does not match a course in this domain.'); } + $output .= '

'; return $output; } } else { @@ -832,17 +989,13 @@ sub print_course_listing { %courses = &search_courselist($domain,$subcats); } if (keys(%courses) == 0) { + $output = '

'; if ($env{'form.currcat_0'} eq 'communities::0') { - $output = - '

' - .&mt('No communities match the criteria you selected.') - .'

'; + $output .= &mt('No communities match the criteria you selected.'); } else { - $output = - '

' - .&mt('No courses match the criteria you selected.') - .'

'; + $output .= &mt('No courses match the criteria you selected.'); } + $output .= '

'; return $output; } if (($knownuser) && (!$env{'form.showdetails'}) && (!&user_is_dc($domain))) { @@ -852,10 +1005,8 @@ sub print_course_listing { } } my $now = time; - my %domconfig = - &Apache::lonnet::get_dom('configuration',['usercreation'],$domain); $output .= &construct_data_table($knownuser,$domain,\%courses,$details,undef, - $now,\%domconfig,$trails,$allitems); + $now,$trails,$allitems); $output .= "\n".'
'. ''. ''. @@ -864,8 +1015,7 @@ sub print_course_listing { } sub construct_data_table { - my ($knownuser,$domain,$courses,$details,$usersections,$now,$domconfig, - $trails,$allitems) = @_; + my ($knownuser,$domain,$courses,$details,$usersections,$now,$trails,$allitems) = @_; my %sortname; if (($details eq '') || ($env{'form.showdetails'})) { $sortname{'Code'} = 'code'; @@ -946,10 +1096,21 @@ sub construct_data_table { } $output .= ''.&mt('Self-enroll (if permitted)').''; &Apache::loncommon::end_data_table_header_row(); - my %numbers; + my (%numbers,%creditsum); + my ($showcredits,$defofficial,$defunofficial,$deftextbook); + my %domdefaults = &Apache::lonnet::get_domain_defaults($domain); + unless ($env{'form.currcat_0'} eq 'communities::0') { + if ($domdefaults{'officialcredits'} || $domdefaults{'unofficialcredits'} || $domdefaults{'textbookcredits'}) { + $showcredits = 1; + $defofficial = $domdefaults{'officialcredits'}; + $defunofficial = $domdefaults{'unofficialcredits'}; + $deftextbook = $domdefaults{'textbookcredits'}; + } + } my %courseinfo = &build_courseinfo_hash($courses,$knownuser,$domain,$details, $usersections,\@fields,\%fieldtitles, - $wasactiveon,\%numbers); + $wasactiveon,\%numbers,\%creditsum, + $showcredits,$defofficial,$defunofficial,$deftextbook); my %Sortby; foreach my $course (sort(keys(%{$courses}))) { if ($env{'form.sortby'} eq 'code') { @@ -992,33 +1153,51 @@ sub construct_data_table { 'Previous' => 'Total previous students', 'courses' => 'Total unique codes and courses without codes', 'sections' => 'Total sections', - 'xlists' => 'Total cross-listings', + 'xlists' => 'Total cross-listings', ); + if ($showcredits) { + $lt{'cr_Active'} = &mt('Total current student credit hours'); + $lt{'cr_Future'} = &mt('Total future student credit hours'); + $lt{'cr_Previous'} = &mt('Total previous student credit hours'); + } 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'); - } + } + my $colspan = 8; + if ($showcredits) { + $colspan = 4; + } $output .= ''. ' '. - ''. + ''. ''; foreach my $item ('courses','sections','xlists') { $output .= ''. - ''. + ''. ''. ''."\n"; } if (@fields > 0) { foreach my $status (@fields) { $output .= ''. - ''. + ''. ''. ''."\n"; } } - $output .= '
'.$lt{$item}.''.$lt{$item}.' '.$numbers{$item}.'
'.$lt{$status}.''.$lt{$status}.' '.$numbers{$status}.'
'; + $output .= ''; + if ($showcredits) { + $output .= ''; + foreach my $status (@fields) { + $output .= ''. + ''. + ''; + } + $output .= '
'.$lt{'cr_'.$status}.' '.$creditsum{$status}.'
'; + } } } $output .= &Apache::loncommon::end_data_table(); @@ -1027,14 +1206,14 @@ sub construct_data_table { sub build_courseinfo_hash { my ($courses,$knownuser,$domain,$details,$usersections,$fields,$fieldtitles, - $wasactiveon,$numbers) = @_; + $wasactiveon,$numbers,$creditsum,$showcredits,$defofficial,$defunofficial) = @_; my %courseinfo; my $now = time; my $gettotals; if ((keys(%{$courses}) > 0) && (&user_is_dc($domain)) && ($details)) { $gettotals = 1; } - my (%uniquecodes,$nocodes),; + my (%uniquecodes,$nocodes,$defcreds); foreach my $course (keys(%{$courses})) { my $descr; if (ref($courses->{$course}) eq 'HASH') { @@ -1116,6 +1295,16 @@ sub build_courseinfo_hash { $showsyllabus = $coursehash{'showsyllabus'}; } $courseinfo{$course}{'showsyllabus'} = $showsyllabus; + if ($showcredits) { + if ($coursehash{'internal.defaultcredits'}) { + $courseinfo{$course}{'defaultcredits'} = $coursehash{'internal.defaultcredits'}; + } elsif ($instcode ne '') { + $courseinfo{$course}{'defaultcredits'} = $defofficial; + } else { + $courseinfo{$course}{'defaultcredits'} = $defunofficial; + } + $defcreds = $courseinfo{$course}{'defaultcredits'}; + } if (((defined($env{'form.coursenum'}) && ($cnum eq $env{'form.coursenum'}))) || ($knownuser && ($details == 1))) { my $milestone; @@ -1136,7 +1325,7 @@ sub build_courseinfo_hash { } $courseinfo{$course}{'counts'} = &count_students($cdom,$cnum,$numsec,$fields,$fieldtitles,$gettotals, - $numbers,$milestone); + $numbers,$creditsum,$showcredits,$defcreds,$milestone); if ($instcode ne '') { $courseinfo{$course}{'autoenrollment'} = &autoenroll_info(\%coursehash,$now,$seclist,$xlist_items, @@ -1201,7 +1390,8 @@ sub build_courseinfo_hash { } sub count_students { - my ($cdom,$cnum,$numsec,$fieldsref,$titlesref,$getcounts,$numbers,$wasactiveon) = @_; + my ($cdom,$cnum,$numsec,$fieldsref,$titlesref,$getcounts,$numbers,$creditsum, + $showcredits,$defcreds,$wasactiveon) = @_; my $countslist = ''. &mt('[quant,_1,section,sections,No sections]',$numsec).''; my (@fields,%titles,$showexpired); @@ -1216,23 +1406,42 @@ sub count_students { return; } my $classlist = &Apache::loncoursedata::get_classlist($cdom,$cnum); - my %student_count = ( + my (%student_count,%credit_count); + %student_count = ( Active => 0, Future => 0, Previous => 0, - ); + ); + if ($showcredits) { + %credit_count = ( + Active => 0, + Future => 0, + Previous => 0, + ); + } my %idx; $idx{'status'} = &Apache::loncoursedata::CL_STATUS(); $idx{'end'} = &Apache::loncoursedata::CL_END(); + $idx{'credits'} = &Apache::loncoursedata::CL_CREDITS(); while (my ($student,$data) = each(%$classlist)) { my $status = $data->[$idx{'status'}]; + my $credits = $data->[$idx{'credits'}]; + if ($credits eq '') { + $credits = $defcreds; + } if ($status eq 'Expired') { if (($showexpired) && ($data->[$idx{'end'}] >= $wasactiveon)) { $student_count{'Previous'} ++; + if ($showcredits) { + $credit_count{'Previous'} += $credits; + } } } else { $student_count{$status} ++; + if ($showcredits) { + $credit_count{$status} += $credits; + } } } if (@fields) { @@ -1241,6 +1450,9 @@ sub count_students { $countslist .= ''.$titles{$status}.': '. $student_count{$status}.'
'; $numbers->{$status} += $student_count{$status}; + if ($showcredits) { + $creditsum->{$status} += $credit_count{$status}; + } } } return $countslist; @@ -1308,29 +1520,39 @@ sub courseinfo_row { $output .= "".&mt('Show more details').''; } } - my $selfenroll; - if ($info->{'selfenroll_types'}) { - my $showstart = &Apache::lonlocal::locallocaltime($info->{'selfenroll_start'}); - my $showend = &Apache::lonlocal::locallocaltime($info->{'selfenroll_end'}); - if (($info->{'selfenroll_end'} > 0) && ($info->{'selfenroll_end'} > $now)) { - if (($info->{'selfenroll_start'} > 0) && ($info->{'selfenroll_start'} > $now)) { - $output .= ''.&mt('Starts: [_1]',''.$showstart.'').'
'.&mt('Ends: [_1]',''.$showend.'').''; - } else { - $output .= ''.&mt('Enroll in course').'
'; - if ($info->{'selfenroll_end'} == 0) { - $output .= &mt('Available permanently'); - } elsif ($info->{'selfenroll_end'} > $now) { - $output .= &mt('Self-enrollment ends: [_1]',''.$showend.''); + my $selfenroll = &selfenroll_status($info,$course); + if ($selfenroll) { + $output .= ''.$selfenroll.''; + } else { + $output .= ' '; + } + $$countref ++; + return $output; +} + +sub selfenroll_status { + my ($info,$course) = @_; + my $now = time; + my $output; + if (ref($info) eq 'HASH') { + if ($info->{'selfenroll_types'}) { + my $showstart = &Apache::lonlocal::locallocaltime($info->{'selfenroll_start'}); + my $showend = &Apache::lonlocal::locallocaltime($info->{'selfenroll_end'}); + if (($info->{'selfenroll_end'} > 0) && ($info->{'selfenroll_end'} > $now)) { + if (($info->{'selfenroll_start'} > 0) && ($info->{'selfenroll_start'} > $now)) { + $output = &mt('Starts: [_1]',''.$showstart.'').'
'.&mt('Ends: [_1]',''.$showend.''); + } else { + $output = ''. + &mt('Enroll in course').'
'; + if ($info->{'selfenroll_end'} == 0) { + $output .= &mt('Available permanently'); + } elsif ($info->{'selfenroll_end'} > $now) { + $output .= &mt('Self-enrollment ends: [_1]',''.$showend.''); + } } - $output .= ''; } - $selfenroll = 1; } } - if (!$selfenroll) { - $output .= ' '; - } - $$countref ++; return $output; }