File:  [LON-CAPA] / loncom / interface / lonviewclasslist.pm
Revision 1.16: download - view: text, annotated - select for diffs
Sun Oct 26 15:20:25 2014 UTC (9 years, 6 months ago) by raeburn
Branches: MAIN
CVS tags: HEAD
- Text used determined by context (either Community or Course).

    1: # The LearningOnline Network with CAPA
    2: # Handler to display the classlist 
    3: #
    4: # $Id: lonviewclasslist.pm,v 1.16 2014/10/26 15:20:25 raeburn Exp $
    5: #
    6: # Copyright Michigan State University Board of Trustees
    7: #
    8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
    9: #
   10: # LON-CAPA is free software; you can redistribute it and/or modify
   11: # it under the terms of the GNU General Public License as published by
   12: # the Free Software Foundation; either version 2 of the License, or
   13: # (at your option) any later version.
   14: #
   15: # LON-CAPA is distributed in the hope that it will be useful,
   16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18: # GNU General Public License for more details.
   19: #
   20: # You should have received a copy of the GNU General Public License
   21: # along with LON-CAPA; if not, write to the Free Software
   22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   23: #
   24: # /home/httpd/html/adm/gpl.txt
   25: #
   26: # http://www.lon-capa.org/
   27: #
   28: ###############################################################
   29: ##############################################################
   30: 
   31: package Apache::lonviewclasslist;
   32: 
   33: use strict;
   34: use Apache::loncoursedata();
   35: use Apache::loncommon();
   36: use Apache::lonhtmlcommon();
   37: use Apache::courseprefs();
   38: use Apache::Constants qw(:common :http REDIRECT);
   39: use Apache::lonlocal;
   40: use Apache::lonnet;
   41: 
   42: 
   43: ###################################################################
   44: ###################################################################
   45: 
   46: =pod
   47: 
   48: =item &handler
   49: 
   50: The typical handler you see in all these modules.  Takes $r, the
   51: http request, as an argument.  
   52: 
   53: =cut
   54: 
   55: ###################################################################
   56: ###################################################################
   57: sub handler {
   58:     my $r=shift;
   59:     if ($r->header_only) {
   60:         &Apache::loncommon::content_type($r,'text/html');
   61:         $r->send_http_header;
   62:         return OK;
   63:     }
   64:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
   65:                                  ['register','forceedit','action','symb','todocs']);
   66:     if (! ($env{'request.course.fn'})) {
   67:         $env{'user.error.msg'}=
   68:             "/adm/viewclasslist:not in course role";
   69:         return HTTP_NOT_ACCEPTABLE; 
   70:     }
   71:     &Apache::loncommon::content_type($r,'text/html');
   72:     $r->send_http_header;
   73:     #
   74:     my $start_page;
   75:     if ($env{'form.register'}) {
   76:         $start_page = &Apache::loncommon::start_page('Classlist',undef,
   77:                              {'force_register' => $env{'form.register'}});
   78:     } else {
   79:         my $brcrum = [{'href' => 'adm/viewclasslist',
   80:                        'text' => 'View Classlist'},];
   81:         $start_page = &Apache::loncommon::start_page('Classlist',undef,
   82:                                                      {'bread_crumbs' => $brcrum});
   83:     }
   84:     $r->print(<<ENDHEADER);
   85: $start_page
   86: ENDHEADER
   87: 
   88:     # Get classlist view settings
   89:     my %viewsettings = &retrieve_view_settings();
   90:     my $crstype = &Apache::loncommon::course_type();
   91: 
   92:     if (($env{'form.forceedit'}) || ($env{'form.action'} eq 'setconfig'))  {
   93:         if (&Apache::lonnet::allowed('opa',$env{'request.course.id'})) {
   94:             my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
   95:             my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
   96:             my $rosterprefs = &roster_prefs($crstype);
   97:             my $allitems = {};
   98:             if ($env{'form.action'} eq 'setconfig') {
   99:                 my %values=&Apache::lonnet::dump('environment',$cdom,$cnum);
  100:                 if (keys(%values) > 0) {
  101:                     my ($numchanged,%changes,%disallowed);
  102:                     my $prefs = {
  103:                                     classlists => $rosterprefs,
  104:                                 };
  105:                     $changes{'classlists'} = {};
  106:                     &Apache::courseprefs::process_changes($cdom,'classlists',\%values,
  107:                                                           $rosterprefs,
  108:                                                           $changes{'classlists'},
  109:                                                           $allitems,\%disallowed,$crstype);
  110:                     my $message;
  111:                     if (keys(%{$changes{'classlists'}}) > 0) {
  112:                         my $actions = ['classlists'];
  113:                         $message =
  114:                             &Apache::courseprefs::store_changes($cdom,$cnum,$actions,
  115:                                                                 $actions,$prefs,\%values,
  116:                                                                 \%changes,$crstype);
  117:                     } else {
  118:                         if ($crstype eq 'Community') {
  119:                             $message = &mt('No changes made to community settings.');
  120:                         } else {
  121:                             $message = &mt('No changes made to course settings.');
  122:                         }
  123:                     }
  124:                     $r->print(&Apache::loncommon::confirmwrapper($message));
  125:                } else {
  126:                     $r->print('<div class="LC_info">'.
  127:                               &mt('Unable to retrieve current settings.').'<br />'.
  128:                               &mt('No changes saved.').
  129:                               '</div>');
  130:                }
  131:            } else {
  132:                my $current = {};
  133:                my @settings = ('student_classlist_view','student_classlist_opt_in',
  134:                                'student_classlist_portfiles');
  135:                foreach my $setting (@settings) {
  136:                    $current->{$setting} = $env{"course.$env{'request.course.id'}.$setting"};
  137:                }
  138:                my ($output,$rowtotal) =
  139:                    &Apache::courseprefs::print_config_box($r,$cdom,'display',
  140:                                                           'viewableroster',
  141:                                                           $rosterprefs,$current,
  142:                                                           $allitems,$crstype);
  143:                if ($output) {
  144:                    $r->print('<form method="post" name="display" action="/adm/viewclasslist">'."\n".
  145:                              '<input type="hidden" name="action" value="setconfig" />'."\n".
  146:                              '<input type="hidden" name="register" value="'.$env{'form.register'}.'" />'."\n".
  147:                              '<input type="hidden" name="forceedit" value="'.$env{'form.forceedit'}.'" />'."\n");
  148:                    if ($env{'form.symb'}) {
  149:                         $r->print('<input type="hidden" name="symb" value="'.$env{'form.symb'}.'" />'."\n");
  150:                    }
  151:                    if ($env{'form.symb'}) {
  152:                         $r->print('<input type="hidden" name="todocs" value="'.$env{'form.todocs'}.'" />'."\n");
  153:                    }
  154:                    $r->print('<div class="LC_left_float">'.
  155:                              $output.
  156:                              '</div><br clear="all" />'.
  157:                              '<input type="submit" value="'.&mt('Save').'" />'.
  158:                              '</form>');
  159:                } else {
  160:                    $r->print('<div class="LC_info">');
  161:                    if ($crstype eq 'Community') {
  162:                        $r->print(&mt('No member-viewable community roster settings available.'));
  163:                    } else {
  164:                        $r->print(&mt('No student-viewable course roster settings available.'));
  165:                    }
  166:                    $r->print('</div>');
  167:                }
  168:            }
  169:         } else {
  170:             $r->print('<div class="LC_info">');
  171:             if ($crstype eq 'Community') {
  172:                 $r->print(&mt('You do not have rights to modify member-viewable community roster settings.'));
  173:             } else {
  174:                 $r->print(&mt('You do not have rights to modify student-viewable course roster settings.'));
  175:             }
  176:             $r->print('</div>');
  177:         }
  178:     } else {
  179: 
  180:         # Print classlist
  181:         if (keys(%viewsettings) > 0) {
  182:             $r->print(&html_classlist($r,$crstype,\%viewsettings));
  183:         } else {
  184:             $r->print('<div class="LC_info">');
  185:             if ($crstype eq 'Community') {
  186:                 $r->print(&mt("Display of a member-viewable community roster is not currently enabled."));
  187:             } else {
  188:                 $r->print(&mt("Display of a student-viewable course roster is not currently enabled."));
  189:             }
  190:             $r->print('</div>');
  191:         }
  192:     }
  193:     #
  194:     # Finish up
  195:     $r->print(&Apache::loncommon::end_page());
  196:     return OK;
  197: }
  198: 
  199: sub retrieve_view_settings {
  200:     my %viewsettings;
  201:     if (exists($env{'request.course.id'})) {
  202:         my $cid = $env{'request.course.id'};
  203:         my $viewpermission = 'course.'.$cid.'.student_classlist_view';
  204:         my $student_opt_in = 'course.'.$cid.'.student_classlist_opt_in';
  205:         my $portfiles_link = 'course.'.$cid.'.student_classlist_portfiles';
  206:         if (exists($env{$viewpermission}) &&
  207:             $env{$viewpermission} =~ /^(all|section)$/) {
  208:             $viewsettings{'permission'} = $env{$viewpermission};
  209:             if ($viewsettings{'permission'} =~ /^section$/i) {
  210:                 $viewsettings{'limit_to_section'} = 1;
  211:             } else {
  212:                 $viewsettings{'limit_to_section'} = 0;
  213:             }
  214:             $viewsettings{'student_opt_in'} = $env{$student_opt_in};
  215:             $viewsettings{'portfiles_link'} = $env{$portfiles_link};
  216:         }
  217:     }
  218:     return %viewsettings;
  219: }
  220: 
  221: sub roster_prefs {
  222:     my ($crstype) = @_;
  223:     my %lt;
  224:     if ($crstype eq 'Community') {
  225:         %lt = &Apache::lonlocal::texthash (
  226:                   svrs => 'Member-viewable roster settings',
  227:                   stuv => 'Member-viewable membership list options',
  228:                   stul => 'Member agreement needed to be listed',
  229:         );
  230:     } else {
  231:         %lt = &Apache::lonlocal::texthash(
  232:                   svrs => 'Student-viewable roster settings',
  233:                   stuv => 'Student-viewable classlist options',
  234:                   stul => 'Student agreement needed to be listed',
  235:         );
  236:     }
  237:     $lt{'incl'} = &mt('Include link to accessible portfolio files');
  238: 
  239:     return 
  240:         { text => $lt{'svrs'},
  241:           header => [ {col1 => 'Setting',
  242:                        col2 => $lt{'stuv'}}],
  243:           ordered => ['student_classlist_view',
  244:                       'student_classlist_opt_in',
  245:                       'student_classlist_portfiles'],
  246:           itemtext => {
  247:                        student_classlist_view        => $lt{'stuv'},
  248:                        student_classlist_opt_in      => $lt{'stul'},
  249:                        student_classlist_portfiles   => $lt{'incl'},
  250:                       },
  251:         };
  252: }
  253: 
  254: sub html_classlist {
  255:     my ($r,$crstype,$viewsettings) = @_;
  256:     my ($Str,$title,$secdisplay,$cid,$cdom,$cnum,$listtype,%publicroster);
  257:     my $fullroster = &Apache::loncoursedata::get_classlist();
  258:     my $classlist;
  259: 
  260:     my $singular = 'student';
  261:     my $plural = 'students';
  262:     my $titleplural = 'Students';
  263:     my $heading = &mt('Student-viewable course roster');
  264: 
  265:     if ($crstype eq 'Community') {
  266:         $singular = 'member';
  267:         $plural = 'members';
  268:         $titleplural = 'Members';
  269:         $heading = &mt('Member-viewable community roster');
  270:     }
  271: 
  272:     if ($env{'form.action'} eq 'setenv') {
  273:         $Str .= &process_student_prefs();
  274:     }
  275: 
  276:     $Str .= '<h2>'.$heading.'</h2>';
  277: 
  278:     $cid = $env{'request.course.id'};
  279:     $cdom = $env{'course.'.$cid.'.domain'};
  280:     $cnum = $env{'course.'.$cid.'.num'};
  281: 
  282:     my $title;
  283:     if ($viewsettings->{'limit_to_section'}) {
  284:         if ($env{'request.course.sec'} eq '') {
  285:             $title = &mt($titleplural.' with no section');
  286:             $listtype = 'without a section';
  287:         } else {
  288:             $title = &mt($titleplural.' in section "[_1]"',
  289:                          $env{'request.course.sec'});
  290:             $listtype = 'in the section';
  291:             $secdisplay = " ($env{'request.course.sec'}) ";
  292:         }
  293:     } else {
  294:         $title = &mt($titleplural.' in any section');
  295:         $listtype = 'in the course';
  296:     }
  297: 
  298:     if ($viewsettings->{'student_opt_in'}) {
  299:         if ($env{'request.role'} =~ /^st/)  {
  300:             $Str .= &print_roster_form();
  301:         }
  302:         %publicroster = &Apache::lonnet::dump('publicroster',$cdom,$cnum);
  303:     }
  304: 
  305:     $Str .= '<h3>'.$title.'</h3>';
  306: 
  307:     my $fullcount = 0;
  308:     my $publiccount = 0;
  309:     my $displaycount = 0;
  310:     my $sectionidx  = &Apache::loncoursedata::CL_SECTION();
  311:     my $statusidx   = &Apache::loncoursedata::CL_STATUS();
  312: 
  313:     foreach my $student (keys(%{$fullroster})) {
  314:         my $section  = $fullroster->{$student}->[$sectionidx];
  315:         my $status   = $fullroster->{$student}->[$statusidx];
  316:         next if (lc($status) ne 'active');
  317:         if ($viewsettings->{'limit_to_section'}) {
  318:             next if ($section ne $env{'request.course.sec'});
  319:         }
  320:         $fullcount ++;
  321:         if ($viewsettings->{'student_opt_in'}) {
  322:             if ($publicroster{$student}) {
  323:                 $classlist->{$student} = $fullroster->{$student};
  324:                 $publiccount ++;
  325:             }
  326:         } else {
  327:             $classlist->{$student} = $fullroster->{$student};
  328:         }
  329:     }
  330:     if ($viewsettings->{'student_opt_in'}) {
  331:         $displaycount = $publiccount;
  332:         if ($fullcount > $publiccount) {
  333:             if ($publiccount) {
  334:                 $Str .= &mt('Only '.$plural.' who have opted to be listed in the roster ([_1] out of [_2] '.$plural.') are shown.',$publiccount,$fullcount).'<br />';
  335:             } else {
  336:                 if ($fullcount == 1) {
  337:                     $Str .= &mt('The single '.$singular.' '.$listtype.'[_1] has opted not to be listed in the roster.',$secdisplay);
  338:                 } else {
  339:                     $Str .= &mt('None of the [_1] '.$plural.' '.$listtype.'[_2] have opted to be listed in the roster.',$fullcount,$secdisplay);
  340:                 }
  341:                 return $Str;
  342:             }
  343:         } else {
  344:             if ($fullcount > 1) {
  345:                 $Str .= &mt('All [_1] '.$plural.' '.$listtype.'[_2] have opted to be listed in the roster.',$fullcount,$secdisplay); 
  346:             } elsif ($fullcount == 1) {
  347:                 $Str .= &mt('The single '.$singular.' '.$listtype.'[_1] has opted to be listed in the roster.',$secdisplay);
  348:             }
  349:         }
  350:     } else {
  351:         $displaycount = $fullcount;
  352:         if ($fullcount > 1) {
  353:             $Str .= &mt('All [_1] '.$plural.' '.$listtype.'[_2] are listed in the roster.',$fullcount,$secdisplay);
  354:         } elsif ($fullcount == 1) {
  355:             $Str .= &mt('There is only a single '.$singular.' '.$listtype.'[_1]',$secdisplay);
  356:         }
  357:     }
  358:     undef($fullroster);
  359: 
  360:     if (!$displaycount) {
  361:         $Str .= &mt('There are currently no '.$plural.' to display.');
  362:         return $Str;
  363:     }
  364: 
  365:     # Set up a couple variables.
  366:     my $usernameidx = &Apache::loncoursedata::CL_SNAME();
  367:     my $domainidx   = &Apache::loncoursedata::CL_SDOM();
  368:     my $fullnameidx = &Apache::loncoursedata::CL_FULLNAME();
  369: 
  370:     # Sort the students
  371:     my $sortby = $fullnameidx;
  372:     my @Sorted_Students = sort {
  373:         lc($classlist->{$a}->[$sortby])  cmp lc($classlist->{$b}->[$sortby])
  374:         } (keys(%$classlist));
  375:     $Str .= '<br />'.&Apache::loncommon::start_data_table()."\n".
  376:             &Apache::loncommon::start_data_table_header_row()."\n".
  377:         '<th></th>'. # for the count
  378:         '<th>'.&mt('Name').'</th>'.
  379:         '<th>'.&mt('Username').'</th>';
  380:     if (! $viewsettings->{'limit_to_section'}) {
  381:         $Str .= '<th>'.&mt('Section').'</th>';
  382:     }
  383:     if ($viewsettings->{'portfiles_link'}) {
  384:         $Str .= '<th>'.&mt('Available Portfolio files').'</th>';
  385:     }
  386:     $Str .= &Apache::loncommon::end_data_table_header_row();
  387:     my $count ++;
  388:     foreach my $student (@Sorted_Students) {
  389:         my $username = $classlist->{$student}->[$usernameidx];
  390:         my $domain   = $classlist->{$student}->[$domainidx];
  391:         my $fullname = $classlist->{$student}->[$fullnameidx];
  392:         if ($fullname =~ /^\s*$/) {
  393:             $fullname = &mt('Name not given');
  394:         }
  395:         my $section  = $classlist->{$student}->[$sectionidx];
  396:         if ($section eq '') {
  397:             $section = &mt('none');
  398:         }
  399:         $Str .= &Apache::loncommon::start_data_table_row()."\n".
  400:             '<td>'.$count++.'</td>'.
  401:             '<td>'.&Apache::loncommon::aboutmewrapper($fullname,
  402:                                                       $username,
  403:                                                       $domain).'</td>'.
  404:             '<td>'.('&nbsp;'x2).
  405:             &Apache::loncommon::messagewrapper
  406:             ('<img src="/adm/lonIcons/mailto.gif" border="0" />&nbsp;'.
  407:              $username.':'.$domain,$username,$domain).'</td>';
  408:         if (! $viewsettings->{'limit_to_section'}) {
  409:             $Str .= '<td>'.$section.'</td>';
  410:         }
  411:         if ($viewsettings->{'portfiles_link'}) {
  412:             my $filecounts = &Apache::lonaboutme::portfolio_files($r,'showlink',undef,undef,$domain,$username,$fullname);
  413:             my $link;
  414:             if (ref($filecounts) eq 'HASH') {
  415:                 $link = &mt('[quant,_1,file,files,No files]',$filecounts->{'both'});
  416:                 if ($filecounts->{'both'} > 0) {
  417:                     $link = '<a href="/adm/'.$domain.'/'.$username.'/aboutme/portfolio?classlist">'.$link.'</a>'; 
  418:                 }
  419:             } else {
  420:                 $link = '<span class="LC_error">'.&mt("Error retrieving file information.").'</span>';
  421:             }
  422:             $Str .= '<td>'.$link.'</td>';
  423:         }
  424:         $Str .= &Apache::loncommon::end_data_table_row()."\n";
  425:     }
  426:     $Str .= &Apache::loncommon::end_data_table();
  427:     return $Str;
  428: }
  429: 
  430: sub print_roster_form {
  431:     my $cid = $env{'request.course.id'};
  432:     my $showinroster = $env{'environment.internal.'.$cid.'.showinroster'};
  433:     my ($showoff,$showon);
  434:     if ($showinroster) {
  435:         $showon = ' checked="checked" ';
  436:         $showoff = ' ';
  437:     } else {
  438:         $showoff = ' checked="checked" ';
  439:         $showon = ' ';
  440:     }
  441:     my $output =
  442:         '<div class="LC_left_float">'
  443:        .'<fieldset><legend>'.&mt('Your roster setting').'</legend>';
  444:     if ($showinroster) {
  445:         $output .= &mt('You are currently listed in the student-viewable roster.');
  446:     } else {
  447:         $output .=  &mt('You are currently [_1]not[_2] listed in the student-viewable roster.','<b>','</b>');
  448:     }
  449:     $output .= '<br />'.&mt('Include yourself in the roster?').'&nbsp;&nbsp;'.
  450:         '<form name="studentparm" method="post" action="">'.
  451:         '<span class="LC_nobreak"><label><input type="radio" name="showinroster" value="1"'.$showon.'/>'.&mt('Yes').'</label>&nbsp;&nbsp;<label>'.
  452:         '<input type="radio" name="showinroster" value="0"'.$showoff.'/>'.&mt('No').
  453:         '</label></span><br /><br />'.
  454:         '<input type="hidden" name="action" value="setenv" />'.
  455:         '<input type="submit" name="studentsubmit" value="'.&mt('Save').'" />'.
  456:         '</form></fieldset></div><br clear="all" />';
  457:     return $output;
  458: }
  459: 
  460: sub process_student_prefs {
  461:     my $cid = $env{'request.course.id'};
  462:     my $cdom = $env{'course.'.$cid.'.domain'};
  463:     my $cnum = $env{'course.'.$cid.'.num'};
  464:     my $uname = $env{'user.name'};
  465:     my $udom = $env{'user.domain'};
  466:     my $student = $uname.':'.$udom;
  467:     my %pubroster = &Apache::lonnet::get('publicroster',[$student],$cdom,$cnum);
  468:     my $visibility = &mt('off');
  469:     my $showinroster = $env{'form.showinroster'};
  470:     if ($showinroster) {
  471:         $visibility = &mt('on');
  472:     }
  473:     my $sturoster = 0;
  474:     if ($pubroster{$student}) {
  475:         $sturoster = 1;
  476:     }
  477:     my $output;
  478:     if ($sturoster ne $showinroster) {
  479:         my %changeHash = (
  480:             'environment.internal.'.$cid.'.showinroster' => $showinroster,
  481:         );
  482:         my $putresult = &Apache::lonnet::put('environment',
  483:                                              \%changeHash,$udom,$uname);
  484:         if ($putresult eq 'ok') {
  485:             &Apache::lonnet::appenv(\%changeHash);
  486:             my $result = &Apache::lonnet::put('publicroster',{$student => $showinroster,},$cdom,$cnum);
  487:             if ($result eq 'ok') {
  488:                 $output .=
  489:                     &Apache::lonhtmlcommon::confirm_success(
  490:                         &mt('Display of your name in the student-viewable roster set to [_1].','<b>'.$visibility.'</b>'));
  491:             } else {
  492:                 $output .=
  493:                     &Apache::lonhtmlcommon::confirm_success(
  494:                         &mt('Error occurred saving display setting.'),1);
  495:             }
  496:         } else {
  497:             $output .=
  498:                 &Apache::lonhtmlcommon::confirm_success(
  499:                     &mt('Error occurred saving display setting.'),1);
  500:         }
  501:     } else {
  502:         $output .=
  503:             &Apache::lonhtmlcommon::confirm_success(
  504:                 &mt('Display of your name in the student-viewable roster unchanged (set to [_1]).','<b>'.$visibility.'</b>'));
  505:     }
  506:     $output = &Apache::loncommon::confirmwrapper($output);
  507:     return $output;
  508: }
  509: 
  510: 
  511: 
  512: 
  513: ###################################################################
  514: ###################################################################
  515: 
  516: 1;
  517: __END__
  518: 
  519: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>