# The LearningOnline Network with CAPA # Handler to display the classlist # # $Id: lonviewclasslist.pm,v 1.16 2014/10/26 15:20:25 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # ############################################################### ############################################################## package Apache::lonviewclasslist; use strict; use Apache::loncoursedata(); use Apache::loncommon(); use Apache::lonhtmlcommon(); use Apache::courseprefs(); use Apache::Constants qw(:common :http REDIRECT); use Apache::lonlocal; use Apache::lonnet; ################################################################### ################################################################### =pod =item &handler The typical handler you see in all these modules. Takes $r, the http request, as an argument. =cut ################################################################### ################################################################### sub handler { my $r=shift; if ($r->header_only) { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK; } &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['register','forceedit','action','symb','todocs']); if (! ($env{'request.course.fn'})) { $env{'user.error.msg'}= "/adm/viewclasslist:not in course role"; return HTTP_NOT_ACCEPTABLE; } &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; # my $start_page; if ($env{'form.register'}) { $start_page = &Apache::loncommon::start_page('Classlist',undef, {'force_register' => $env{'form.register'}}); } else { my $brcrum = [{'href' => 'adm/viewclasslist', 'text' => 'View Classlist'},]; $start_page = &Apache::loncommon::start_page('Classlist',undef, {'bread_crumbs' => $brcrum}); } $r->print(< 0) { my ($numchanged,%changes,%disallowed); my $prefs = { classlists => $rosterprefs, }; $changes{'classlists'} = {}; &Apache::courseprefs::process_changes($cdom,'classlists',\%values, $rosterprefs, $changes{'classlists'}, $allitems,\%disallowed,$crstype); my $message; if (keys(%{$changes{'classlists'}}) > 0) { my $actions = ['classlists']; $message = &Apache::courseprefs::store_changes($cdom,$cnum,$actions, $actions,$prefs,\%values, \%changes,$crstype); } else { if ($crstype eq 'Community') { $message = &mt('No changes made to community settings.'); } else { $message = &mt('No changes made to course settings.'); } } $r->print(&Apache::loncommon::confirmwrapper($message)); } else { $r->print('
'. &mt('Unable to retrieve current settings.').'
'. &mt('No changes saved.'). '
'); } } else { my $current = {}; my @settings = ('student_classlist_view','student_classlist_opt_in', 'student_classlist_portfiles'); foreach my $setting (@settings) { $current->{$setting} = $env{"course.$env{'request.course.id'}.$setting"}; } my ($output,$rowtotal) = &Apache::courseprefs::print_config_box($r,$cdom,'display', 'viewableroster', $rosterprefs,$current, $allitems,$crstype); if ($output) { $r->print('
'."\n". ''."\n". ''."\n". ''."\n"); if ($env{'form.symb'}) { $r->print(''."\n"); } if ($env{'form.symb'}) { $r->print(''."\n"); } $r->print('
'. $output. '

'. ''. '
'); } else { $r->print('
'); if ($crstype eq 'Community') { $r->print(&mt('No member-viewable community roster settings available.')); } else { $r->print(&mt('No student-viewable course roster settings available.')); } $r->print('
'); } } } else { $r->print('
'); if ($crstype eq 'Community') { $r->print(&mt('You do not have rights to modify member-viewable community roster settings.')); } else { $r->print(&mt('You do not have rights to modify student-viewable course roster settings.')); } $r->print('
'); } } else { # Print classlist if (keys(%viewsettings) > 0) { $r->print(&html_classlist($r,$crstype,\%viewsettings)); } else { $r->print('
'); if ($crstype eq 'Community') { $r->print(&mt("Display of a member-viewable community roster is not currently enabled.")); } else { $r->print(&mt("Display of a student-viewable course roster is not currently enabled.")); } $r->print('
'); } } # # Finish up $r->print(&Apache::loncommon::end_page()); return OK; } sub retrieve_view_settings { my %viewsettings; if (exists($env{'request.course.id'})) { my $cid = $env{'request.course.id'}; my $viewpermission = 'course.'.$cid.'.student_classlist_view'; my $student_opt_in = 'course.'.$cid.'.student_classlist_opt_in'; my $portfiles_link = 'course.'.$cid.'.student_classlist_portfiles'; if (exists($env{$viewpermission}) && $env{$viewpermission} =~ /^(all|section)$/) { $viewsettings{'permission'} = $env{$viewpermission}; if ($viewsettings{'permission'} =~ /^section$/i) { $viewsettings{'limit_to_section'} = 1; } else { $viewsettings{'limit_to_section'} = 0; } $viewsettings{'student_opt_in'} = $env{$student_opt_in}; $viewsettings{'portfiles_link'} = $env{$portfiles_link}; } } return %viewsettings; } sub roster_prefs { my ($crstype) = @_; my %lt; if ($crstype eq 'Community') { %lt = &Apache::lonlocal::texthash ( svrs => 'Member-viewable roster settings', stuv => 'Member-viewable membership list options', stul => 'Member agreement needed to be listed', ); } else { %lt = &Apache::lonlocal::texthash( svrs => 'Student-viewable roster settings', stuv => 'Student-viewable classlist options', stul => 'Student agreement needed to be listed', ); } $lt{'incl'} = &mt('Include link to accessible portfolio files'); return { text => $lt{'svrs'}, header => [ {col1 => 'Setting', col2 => $lt{'stuv'}}], ordered => ['student_classlist_view', 'student_classlist_opt_in', 'student_classlist_portfiles'], itemtext => { student_classlist_view => $lt{'stuv'}, student_classlist_opt_in => $lt{'stul'}, student_classlist_portfiles => $lt{'incl'}, }, }; } sub html_classlist { my ($r,$crstype,$viewsettings) = @_; my ($Str,$title,$secdisplay,$cid,$cdom,$cnum,$listtype,%publicroster); my $fullroster = &Apache::loncoursedata::get_classlist(); my $classlist; my $singular = 'student'; my $plural = 'students'; my $titleplural = 'Students'; my $heading = &mt('Student-viewable course roster'); if ($crstype eq 'Community') { $singular = 'member'; $plural = 'members'; $titleplural = 'Members'; $heading = &mt('Member-viewable community roster'); } if ($env{'form.action'} eq 'setenv') { $Str .= &process_student_prefs(); } $Str .= '

'.$heading.'

'; $cid = $env{'request.course.id'}; $cdom = $env{'course.'.$cid.'.domain'}; $cnum = $env{'course.'.$cid.'.num'}; my $title; if ($viewsettings->{'limit_to_section'}) { if ($env{'request.course.sec'} eq '') { $title = &mt($titleplural.' with no section'); $listtype = 'without a section'; } else { $title = &mt($titleplural.' in section "[_1]"', $env{'request.course.sec'}); $listtype = 'in the section'; $secdisplay = " ($env{'request.course.sec'}) "; } } else { $title = &mt($titleplural.' in any section'); $listtype = 'in the course'; } if ($viewsettings->{'student_opt_in'}) { if ($env{'request.role'} =~ /^st/) { $Str .= &print_roster_form(); } %publicroster = &Apache::lonnet::dump('publicroster',$cdom,$cnum); } $Str .= '

'.$title.'

'; my $fullcount = 0; my $publiccount = 0; my $displaycount = 0; my $sectionidx = &Apache::loncoursedata::CL_SECTION(); my $statusidx = &Apache::loncoursedata::CL_STATUS(); foreach my $student (keys(%{$fullroster})) { my $section = $fullroster->{$student}->[$sectionidx]; my $status = $fullroster->{$student}->[$statusidx]; next if (lc($status) ne 'active'); if ($viewsettings->{'limit_to_section'}) { next if ($section ne $env{'request.course.sec'}); } $fullcount ++; if ($viewsettings->{'student_opt_in'}) { if ($publicroster{$student}) { $classlist->{$student} = $fullroster->{$student}; $publiccount ++; } } else { $classlist->{$student} = $fullroster->{$student}; } } if ($viewsettings->{'student_opt_in'}) { $displaycount = $publiccount; if ($fullcount > $publiccount) { if ($publiccount) { $Str .= &mt('Only '.$plural.' who have opted to be listed in the roster ([_1] out of [_2] '.$plural.') are shown.',$publiccount,$fullcount).'
'; } else { if ($fullcount == 1) { $Str .= &mt('The single '.$singular.' '.$listtype.'[_1] has opted not to be listed in the roster.',$secdisplay); } else { $Str .= &mt('None of the [_1] '.$plural.' '.$listtype.'[_2] have opted to be listed in the roster.',$fullcount,$secdisplay); } return $Str; } } else { if ($fullcount > 1) { $Str .= &mt('All [_1] '.$plural.' '.$listtype.'[_2] have opted to be listed in the roster.',$fullcount,$secdisplay); } elsif ($fullcount == 1) { $Str .= &mt('The single '.$singular.' '.$listtype.'[_1] has opted to be listed in the roster.',$secdisplay); } } } else { $displaycount = $fullcount; if ($fullcount > 1) { $Str .= &mt('All [_1] '.$plural.' '.$listtype.'[_2] are listed in the roster.',$fullcount,$secdisplay); } elsif ($fullcount == 1) { $Str .= &mt('There is only a single '.$singular.' '.$listtype.'[_1]',$secdisplay); } } undef($fullroster); if (!$displaycount) { $Str .= &mt('There are currently no '.$plural.' to display.'); return $Str; } # Set up a couple variables. my $usernameidx = &Apache::loncoursedata::CL_SNAME(); my $domainidx = &Apache::loncoursedata::CL_SDOM(); my $fullnameidx = &Apache::loncoursedata::CL_FULLNAME(); # Sort the students my $sortby = $fullnameidx; my @Sorted_Students = sort { lc($classlist->{$a}->[$sortby]) cmp lc($classlist->{$b}->[$sortby]) } (keys(%$classlist)); $Str .= '
'.&Apache::loncommon::start_data_table()."\n". &Apache::loncommon::start_data_table_header_row()."\n". ''. # for the count ''.&mt('Name').''. ''.&mt('Username').''; if (! $viewsettings->{'limit_to_section'}) { $Str .= ''.&mt('Section').''; } if ($viewsettings->{'portfiles_link'}) { $Str .= ''.&mt('Available Portfolio files').''; } $Str .= &Apache::loncommon::end_data_table_header_row(); my $count ++; foreach my $student (@Sorted_Students) { my $username = $classlist->{$student}->[$usernameidx]; my $domain = $classlist->{$student}->[$domainidx]; my $fullname = $classlist->{$student}->[$fullnameidx]; if ($fullname =~ /^\s*$/) { $fullname = &mt('Name not given'); } my $section = $classlist->{$student}->[$sectionidx]; if ($section eq '') { $section = &mt('none'); } $Str .= &Apache::loncommon::start_data_table_row()."\n". ''.$count++.''. ''.&Apache::loncommon::aboutmewrapper($fullname, $username, $domain).''. ''.(' 'x2). &Apache::loncommon::messagewrapper (' '. $username.':'.$domain,$username,$domain).''; if (! $viewsettings->{'limit_to_section'}) { $Str .= ''.$section.''; } if ($viewsettings->{'portfiles_link'}) { my $filecounts = &Apache::lonaboutme::portfolio_files($r,'showlink',undef,undef,$domain,$username,$fullname); my $link; if (ref($filecounts) eq 'HASH') { $link = &mt('[quant,_1,file,files,No files]',$filecounts->{'both'}); if ($filecounts->{'both'} > 0) { $link = ''.$link.''; } } else { $link = ''.&mt("Error retrieving file information.").''; } $Str .= ''.$link.''; } $Str .= &Apache::loncommon::end_data_table_row()."\n"; } $Str .= &Apache::loncommon::end_data_table(); return $Str; } sub print_roster_form { my $cid = $env{'request.course.id'}; my $showinroster = $env{'environment.internal.'.$cid.'.showinroster'}; my ($showoff,$showon); if ($showinroster) { $showon = ' checked="checked" '; $showoff = ' '; } else { $showoff = ' checked="checked" '; $showon = ' '; } my $output = '
' .'
'.&mt('Your roster setting').''; if ($showinroster) { $output .= &mt('You are currently listed in the student-viewable roster.'); } else { $output .= &mt('You are currently [_1]not[_2] listed in the student-viewable roster.','',''); } $output .= '
'.&mt('Include yourself in the roster?').'  '. '
'. '  

'. ''. ''. '

'; return $output; } sub process_student_prefs { my $cid = $env{'request.course.id'}; my $cdom = $env{'course.'.$cid.'.domain'}; my $cnum = $env{'course.'.$cid.'.num'}; my $uname = $env{'user.name'}; my $udom = $env{'user.domain'}; my $student = $uname.':'.$udom; my %pubroster = &Apache::lonnet::get('publicroster',[$student],$cdom,$cnum); my $visibility = &mt('off'); my $showinroster = $env{'form.showinroster'}; if ($showinroster) { $visibility = &mt('on'); } my $sturoster = 0; if ($pubroster{$student}) { $sturoster = 1; } my $output; if ($sturoster ne $showinroster) { my %changeHash = ( 'environment.internal.'.$cid.'.showinroster' => $showinroster, ); my $putresult = &Apache::lonnet::put('environment', \%changeHash,$udom,$uname); if ($putresult eq 'ok') { &Apache::lonnet::appenv(\%changeHash); my $result = &Apache::lonnet::put('publicroster',{$student => $showinroster,},$cdom,$cnum); if ($result eq 'ok') { $output .= &Apache::lonhtmlcommon::confirm_success( &mt('Display of your name in the student-viewable roster set to [_1].',''.$visibility.'')); } else { $output .= &Apache::lonhtmlcommon::confirm_success( &mt('Error occurred saving display setting.'),1); } } else { $output .= &Apache::lonhtmlcommon::confirm_success( &mt('Error occurred saving display setting.'),1); } } else { $output .= &Apache::lonhtmlcommon::confirm_success( &mt('Display of your name in the student-viewable roster unchanged (set to [_1]).',''.$visibility.'')); } $output = &Apache::loncommon::confirmwrapper($output); return $output; } ################################################################### ################################################################### 1; __END__