File:  [LON-CAPA] / loncom / interface / lonviewclasslist.pm
Revision 1.15: download - view: text, annotated - select for diffs
Mon Jul 15 17:00:19 2013 UTC (10 years, 9 months ago) by bisitz
Branches: MAIN
CVS tags: version_2_11_0_RC3, version_2_11_0_RC2, version_2_11_0_RC1, version_2_11_0, HEAD
- Improved and consistent layout:
    - confirm_success
    - headlines
    - fieldset for settings
- Exclude HTML from translation phrases
- XHTML: action attribute in <form> required

    1: # The LearningOnline Network with CAPA
    2: # Handler to display the classlist 
    3: #
    4: # $Id: lonviewclasslist.pm,v 1.15 2013/07/15 17:00:19 bisitz 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: 
   91:     if (($env{'form.forceedit'}) || ($env{'form.action'} eq 'setconfig'))  {
   92:         if (&Apache::lonnet::allowed('opa',$env{'request.course.id'})) {
   93:             my $crstype = &Apache::loncommon::course_type();
   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:                              &mt('No student-viewable course roster settings available.').
  162:                              '</div>');
  163:                }
  164:            }
  165:         } else {
  166:             $r->print('<div class="LC_info">'.
  167:                       &mt('You do not have rights to modify student-viewable course roster settings.').
  168:                       '</div>');
  169:         }
  170:     } else {
  171: 
  172:         # Print classlist
  173:         if (keys(%viewsettings) > 0) {
  174:             $r->print(&html_classlist($r,\%viewsettings));
  175:         } else {
  176:             $r->print('<div class="LC_info">'.
  177:                       &mt("Display of a student-viewable course roster is not currently enabled.").
  178:                       '</div>');
  179:         }
  180:     }
  181:     #
  182:     # Finish up
  183:     $r->print(&Apache::loncommon::end_page());
  184:     return OK;
  185: }
  186: 
  187: sub retrieve_view_settings {
  188:     my %viewsettings;
  189:     if (exists($env{'request.course.id'})) {
  190:         my $cid = $env{'request.course.id'};
  191:         my $viewpermission = 'course.'.$cid.'.student_classlist_view';
  192:         my $student_opt_in = 'course.'.$cid.'.student_classlist_opt_in';
  193:         my $portfiles_link = 'course.'.$cid.'.student_classlist_portfiles';
  194:         if (exists($env{$viewpermission}) &&
  195:             $env{$viewpermission} =~ /^(all|section)$/) {
  196:             $viewsettings{'permission'} = $env{$viewpermission};
  197:             if ($viewsettings{'permission'} =~ /^section$/i) {
  198:                 $viewsettings{'limit_to_section'} = 1;
  199:             } else {
  200:                 $viewsettings{'limit_to_section'} = 0;
  201:             }
  202:             $viewsettings{'student_opt_in'} = $env{$student_opt_in};
  203:             $viewsettings{'portfiles_link'} = $env{$portfiles_link};
  204:         }
  205:     }
  206:     return %viewsettings;
  207: }
  208: 
  209: sub roster_prefs {
  210:     my ($crstype) = @_;
  211:     my %lt;
  212:     if ($crstype eq 'Community') {
  213:         %lt = &Apache::lonlocal::texthash (
  214:                   stuv => 'Member-viewable membership list options',
  215:                   stul => 'Member agreement needed to be listed',
  216:         );
  217:     } else {
  218:         %lt = &Apache::lonlocal::texthash(
  219:                   stuv => 'Student-viewable classlist options',
  220:                   stul => 'Student agreement needed to be listed',
  221:         );
  222:     }
  223:     $lt{'incl'} = &mt('Include link to accessible portfolio files');
  224: 
  225:     return 
  226:         { text => 'Student-viewable roster settings',
  227:           header => [ {col1 => 'Setting',
  228:                        col2 => $lt{'stuv'}}],
  229:           ordered => ['student_classlist_view',
  230:                       'student_classlist_opt_in',
  231:                       'student_classlist_portfiles'],
  232:           itemtext => {
  233:                        student_classlist_view        => $lt{'stuv'},
  234:                        student_classlist_opt_in      => $lt{'stul'},
  235:                        student_classlist_portfiles   => $lt{'incl'},
  236:                       },
  237:         };
  238: }
  239: 
  240: sub html_classlist {
  241:     my ($r,$viewsettings) = @_;
  242:     my ($Str,$title,$secdisplay,$cid,$cdom,$cnum,$listtype,%publicroster);
  243:     my $fullroster = &Apache::loncoursedata::get_classlist();
  244:     my $classlist;
  245: 
  246:     if ($env{'form.action'} eq 'setenv') {
  247:         $Str .= &process_student_prefs();
  248:     }
  249:     $Str .= '<h2>'.&mt('Student-viewable course roster').'</h2>';
  250: 
  251:     $cid = $env{'request.course.id'};
  252:     $cdom = $env{'course.'.$cid.'.domain'};
  253:     $cnum = $env{'course.'.$cid.'.num'};
  254: 
  255:     if ($viewsettings->{'limit_to_section'}) {
  256:         if ($env{'request.course.sec'} eq '') {
  257:             $title = '<h3>'.&mt('Students with no section').'</h3>';
  258:             $listtype = 'without a section';
  259:         } else {
  260:             $title ='<h3>'.&mt('Students in section "[_1]"',
  261:                                $env{'request.course.sec'}).'</h3>';
  262:             $listtype = 'in the section';
  263:             $secdisplay = " ($env{'request.course.sec'}) ";
  264:         }
  265:     } else {
  266:         $title .= '<h3>'.&mt('Students in any section').'</h3>';
  267:         $listtype = 'in the course';
  268:     }
  269: 
  270:     if ($viewsettings->{'student_opt_in'}) {
  271:         if ($env{'request.role'} =~ /^st/)  {
  272:             $Str .= &print_roster_form();
  273:         }
  274:         %publicroster = &Apache::lonnet::dump('publicroster',$cdom,$cnum);
  275:     }
  276: 
  277:     $Str .= $title;
  278: 
  279:     my $fullcount = 0;
  280:     my $publiccount = 0;
  281:     my $displaycount = 0;
  282:     my $sectionidx  = &Apache::loncoursedata::CL_SECTION();
  283:     my $statusidx   = &Apache::loncoursedata::CL_STATUS();
  284: 
  285:     foreach my $student (keys(%{$fullroster})) {
  286:         my $section  = $fullroster->{$student}->[$sectionidx];
  287:         my $status   = $fullroster->{$student}->[$statusidx];
  288:         next if (lc($status) ne 'active');
  289:         if ($viewsettings->{'limit_to_section'}) {
  290:             next if ($section ne $env{'request.course.sec'});
  291:         }
  292:         $fullcount ++;
  293:         if ($viewsettings->{'student_opt_in'}) {
  294:             if ($publicroster{$student}) {
  295:                 $classlist->{$student} = $fullroster->{$student};
  296:                 $publiccount ++;
  297:             }
  298:         } else {
  299:             $classlist->{$student} = $fullroster->{$student};
  300:         }
  301:     }
  302:     if ($viewsettings->{'student_opt_in'}) {
  303:         $displaycount = $publiccount;
  304:         if ($fullcount > $publiccount) {
  305:             if ($publiccount) {
  306:                 $Str .= &mt('Only students who have opted to be listed in the roster ([_1] out of [_2] students) are shown.',$publiccount,$fullcount).'<br />';
  307:             } else {
  308:                 if ($fullcount == 1) {
  309:                     $Str .= &mt('The single student '.$listtype.'[_1] has opted not to be listed in the roster.',$secdisplay);
  310:                 } else {
  311:                     $Str .= &mt('None of the [_1] students '.$listtype.'[_2] have opted to be listed in the roster.',$fullcount,$secdisplay);
  312:                 }
  313:                 return $Str;
  314:             }
  315:         } else {
  316:             if ($fullcount > 1) {
  317:                 $Str .= &mt('All [_1] students '.$listtype.'[_2] have opted to be listed in the roster.',$fullcount,$secdisplay);
  318:             } elsif ($fullcount == 1) {
  319:                 $Str .= &mt('The single student '.$listtype.'[_1] has opted to be listed in the roster.',$secdisplay);
  320:             }
  321:         }
  322:     } else {
  323:         $displaycount = $fullcount;
  324:         if ($fullcount > 1) {
  325:             $Str .= &mt('All [_1] students '.$listtype.'[_2] are listed in the roster.',$fullcount,$secdisplay);
  326:         } elsif ($fullcount == 1) {
  327:             $Str .= &mt('There is only a single student '.$listtype.'[_1]',$secdisplay);
  328:         }
  329:     }
  330:     undef($fullroster);
  331: 
  332:     if (!$displaycount) {
  333:         $Str .= &mt('There are currently no students to display.');
  334:         return $Str;
  335:     }
  336: 
  337:     # Set up a couple variables.
  338:     my $usernameidx = &Apache::loncoursedata::CL_SNAME();
  339:     my $domainidx   = &Apache::loncoursedata::CL_SDOM();
  340:     my $fullnameidx = &Apache::loncoursedata::CL_FULLNAME();
  341: 
  342:     # Sort the students
  343:     my $sortby = $fullnameidx;
  344:     my @Sorted_Students = sort {
  345:         lc($classlist->{$a}->[$sortby])  cmp lc($classlist->{$b}->[$sortby])
  346:         } (keys(%$classlist));
  347:     $Str .= '<br />'.&Apache::loncommon::start_data_table()."\n".
  348:             &Apache::loncommon::start_data_table_header_row()."\n".
  349:         '<th></th>'. # for the count
  350:         '<th>'.&mt('Student').'</th>'.
  351:         '<th>'.&mt('Username').'</th>';
  352:     if (! $viewsettings->{'limit_to_section'}) {
  353:         $Str .= '<th>'.&mt('Section').'</th>';
  354:     }
  355:     if ($viewsettings->{'portfiles_link'}) {
  356:         $Str .= '<th>'.&mt('Available Portfolio files').'</th>';
  357:     }
  358:     $Str .= &Apache::loncommon::end_data_table_header_row();
  359:     my $count ++;
  360:     foreach my $student (@Sorted_Students) {
  361:         my $username = $classlist->{$student}->[$usernameidx];
  362:         my $domain   = $classlist->{$student}->[$domainidx];
  363:         my $fullname = $classlist->{$student}->[$fullnameidx];
  364:         if ($fullname =~ /^\s*$/) {
  365:             $fullname = &mt('Name not given');
  366:         }
  367:         my $section  = $classlist->{$student}->[$sectionidx];
  368:         if ($section eq '') {
  369:             $section = &mt('none');
  370:         }
  371:         $Str .= &Apache::loncommon::start_data_table_row()."\n".
  372:             '<td>'.$count++.'</td>'.
  373:             '<td>'.&Apache::loncommon::aboutmewrapper($fullname,
  374:                                                       $username,
  375:                                                       $domain).'</td>'.
  376:             '<td>'.('&nbsp;'x2).
  377:             &Apache::loncommon::messagewrapper
  378:             ('<img src="/adm/lonIcons/mailto.gif" border="0" />&nbsp;'.
  379:              $username.':'.$domain,$username,$domain).'</td>';
  380:         if (! $viewsettings->{'limit_to_section'}) {
  381:             $Str .= '<td>'.$section.'</td>';
  382:         }
  383:         if ($viewsettings->{'portfiles_link'}) {
  384:             my $filecounts = &Apache::lonaboutme::portfolio_files($r,'showlink',undef,undef,$domain,$username,$fullname);
  385:             my $link;
  386:             if (ref($filecounts) eq 'HASH') {
  387:                 $link = &mt('[quant,_1,file,files,No files]',$filecounts->{'both'});
  388:                 if ($filecounts->{'both'} > 0) {
  389:                     $link = '<a href="/adm/'.$domain.'/'.$username.'/aboutme/portfolio?classlist">'.$link.'</a>'; 
  390:                 }
  391:             } else {
  392:                 $link = '<span class="LC_error">'.&mt("Error retrieving file information.").'</span>';
  393:             }
  394:             $Str .= '<td>'.$link.'</td>';
  395:         }
  396:         $Str .= &Apache::loncommon::end_data_table_row()."\n";
  397:     }
  398:     $Str .= &Apache::loncommon::end_data_table();
  399:     return $Str;
  400: }
  401: 
  402: sub print_roster_form {
  403:     my $cid = $env{'request.course.id'};
  404:     my $showinroster = $env{'environment.internal.'.$cid.'.showinroster'};
  405:     my ($showoff,$showon);
  406:     if ($showinroster) {
  407:         $showon = ' checked="checked" ';
  408:         $showoff = ' ';
  409:     } else {
  410:         $showoff = ' checked="checked" ';
  411:         $showon = ' ';
  412:     }
  413:     my $output =
  414:         '<div class="LC_left_float">'
  415:        .'<fieldset><legend>'.&mt('Your roster setting').'</legend>';
  416:     if ($showinroster) {
  417:         $output .= &mt('You are currently listed in the student-viewable roster.');
  418:     } else {
  419:         $output .=  &mt('You are currently [_1]not[_2] listed in the student-viewable roster.','<b>','</b>');
  420:     }
  421:     $output .= '<br />'.&mt('Include yourself in the roster?').'&nbsp;&nbsp;'.
  422:         '<form name="studentparm" method="post" action="">'.
  423:         '<span class="LC_nobreak"><label><input type="radio" name="showinroster" value="1"'.$showon.'/>'.&mt('Yes').'</label>&nbsp;&nbsp;<label>'.
  424:         '<input type="radio" name="showinroster" value="0"'.$showoff.'/>'.&mt('No').
  425:         '</label></span><br /><br />'.
  426:         '<input type="hidden" name="action" value="setenv" />'.
  427:         '<input type="submit" name="studentsubmit" value="'.&mt('Save').'" />'.
  428:         '</form></fieldset></div><br clear="all" />';
  429:     return $output;
  430: }
  431: 
  432: sub process_student_prefs {
  433:     my $cid = $env{'request.course.id'};
  434:     my $cdom = $env{'course.'.$cid.'.domain'};
  435:     my $cnum = $env{'course.'.$cid.'.num'};
  436:     my $uname = $env{'user.name'};
  437:     my $udom = $env{'user.domain'};
  438:     my $student = $uname.':'.$udom;
  439:     my %pubroster = &Apache::lonnet::get('publicroster',[$student],$cdom,$cnum);
  440:     my $visibility = &mt('off');
  441:     my $showinroster = $env{'form.showinroster'};
  442:     if ($showinroster) {
  443:         $visibility = &mt('on');
  444:     }
  445:     my $sturoster = 0;
  446:     if ($pubroster{$student}) {
  447:         $sturoster = 1;
  448:     }
  449:     my $output;
  450:     if ($sturoster ne $showinroster) {
  451:         my %changeHash = (
  452:             'environment.internal.'.$cid.'.showinroster' => $showinroster,
  453:         );
  454:         my $putresult = &Apache::lonnet::put('environment',
  455:                                              \%changeHash,$udom,$uname);
  456:         if ($putresult eq 'ok') {
  457:             &Apache::lonnet::appenv(\%changeHash);
  458:             my $result = &Apache::lonnet::put('publicroster',{$student => $showinroster,},$cdom,$cnum);
  459:             if ($result eq 'ok') {
  460:                 $output .=
  461:                     &Apache::lonhtmlcommon::confirm_success(
  462:                         &mt('Display of your name in the student-viewable roster set to [_1].','<b>'.$visibility.'</b>'));
  463:             } else {
  464:                 $output .=
  465:                     &Apache::lonhtmlcommon::confirm_success(
  466:                         &mt('Error occurred saving display setting.'),1);
  467:             }
  468:         } else {
  469:             $output .=
  470:                 &Apache::lonhtmlcommon::confirm_success(
  471:                     &mt('Error occurred saving display setting.'),1);
  472:         }
  473:     } else {
  474:         $output .=
  475:             &Apache::lonhtmlcommon::confirm_success(
  476:                 &mt('Display of your name in the student-viewable roster unchanged (set to [_1]).','<b>'.$visibility.'</b>'));
  477:     }
  478:     $output = &Apache::loncommon::confirmwrapper($output);
  479:     return $output;
  480: }
  481: 
  482: 
  483: 
  484: 
  485: ###################################################################
  486: ###################################################################
  487: 
  488: 1;
  489: __END__
  490: 
  491: 

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