Annotation of loncom/interface/londropadd.pm, revision 1.175

1.1       www         1: # The LearningOnline Network with CAPA
                      2: # Handler to drop and add students in courses 
                      3: #
1.175   ! jms         4: # $Id: londropadd.pm,v 1.174 2008/09/11 14:47:21 bisitz Exp $
1.17      albertel    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: #
1.1       www        28: #
1.175   ! jms        29: 
        !            30: =head1 NAME
        !            31: 
        !            32: Apache::londropadd
        !            33: 
        !            34: =head1 SYNOPSIS
        !            35: 
        !            36: drop & add students
        !            37: 
        !            38: This is part of the LearningOnline Network with CAPA project
        !            39: described at http://www.lon-capa.org.
        !            40: 
        !            41: =head1 SUBROUTINES
        !            42: 
        !            43: =over
        !            44: 
        !            45: =cut
1.1       www        46: 
                     47: package Apache::londropadd;
                     48: 
                     49: use strict;
1.127     albertel   50: use Apache::lonnet;
1.24      albertel   51: use Apache::loncommon();
1.50      matthew    52: use Apache::lonhtmlcommon();
1.1       www        53: use Apache::Constants qw(:common :http REDIRECT);
1.60      matthew    54: use Spreadsheet::WriteExcel;
1.110     matthew    55: use Apache::lonstathelpers();
1.86      www        56: use Apache::lonlocal;
1.143     raeburn    57: use Apache::longroup;
1.152     albertel   58: use LONCAPA();
1.1       www        59: 
1.10      www        60: sub header {
1.166     raeburn    61:     my ($jscript,$loaditems) = @_;
                     62:     my $start_page;
                     63:     if (ref($loaditems) eq 'HASH') {
                     64:         $start_page=&Apache::loncommon::start_page('Enrollment Manager',$jscript,{'add_entries' => $loaditems,});
                     65:     } else {
                     66:         $start_page=&Apache::loncommon::start_page('Enrollment Manager',$jscript);
                     67:     }
1.27      matthew    68:     return(<<ENDHEAD);
1.138     albertel   69: $start_page
1.40      matthew    70: <form method="post" enctype="multipart/form-data"  
                     71:       action="/adm/dropadd" name="studentform">
1.1       www        72: ENDHEAD
1.10      www        73: }
                     74: 
1.175   ! jms        75: =pod
        !            76: 
        !            77: =item modifystudent()
        !            78: 
        !            79:     Drop student from all sections of a course, except optional $csec
        !            80: 
        !            81: =cut
        !            82: 
1.26      matthew    83: sub modifystudent {
1.33      matthew    84:     my ($udom,$unam,$courseid,$csec,$desiredhost)=@_;
1.26      matthew    85:     # if $csec is undefined, drop the student from all the courses matching
                     86:     # this one.  If $csec is defined, drop them from all other sections of 
                     87:     # this course and add them to section $csec
1.151     albertel   88:     my $cdom = $env{'course.'.$courseid.'.domain'};
                     89:     my $cnum = $env{'course.'.$courseid.'.num'};
1.26      matthew    90:     my %roles = &Apache::lonnet::dump('roles',$udom,$unam);
                     91:     my ($tmp) = keys(%roles);
                     92:     # Bail out if we were unable to get the students roles
1.35      matthew    93:     return "$1" if ($tmp =~ /^(con_lost|error|no_such_host)/i);
1.26      matthew    94:     # Go through the roles looking for enrollment in this course
1.35      matthew    95:     my $result = '';
1.26      matthew    96:     foreach my $course (keys(%roles)) {
1.150     albertel   97:         if ($course=~m{^/\Q$cdom\E/\Q$cnum\E(?:\/)*(?:\s+)*(\w+)*\_st$}) {
1.26      matthew    98:             # We are in this course
1.25      matthew    99:             my $section=$1;
1.150     albertel  100:             $section='' if ($course eq "/$cdom/$cnum".'_st');
1.87      matthew   101:             if (defined($csec) && $section eq $csec) {
1.71      matthew   102:                 $result .= 'ok:';
                    103:             } elsif ( ((!$section) && (!$csec)) || ($section ne $csec) ) {
1.27      matthew   104:                 my (undef,$end,$start)=split(/\_/,$roles{$course});
1.25      matthew   105:                 my $now=time;
1.143     raeburn   106:                 # if this is an active role
1.27      matthew   107:                 if (!($start && ($now<$start)) || !($end && ($now>$end))) {
1.25      matthew   108:                     my $reply=&Apache::lonnet::modifystudent
1.70      matthew   109:                         # dom  name  id mode pass     f     m     l     g
                    110:                         ($udom,$unam,'',  '',  '',undef,undef,undef,undef,
1.33      matthew   111:                          $section,time,undef,undef,$desiredhost);
1.35      matthew   112:                     $result .= $reply.':';
1.25      matthew   113:                 }
1.10      www       114:             }
                    115:         }
1.20      harris41  116:     }
1.35      matthew   117:     if ($result eq '') {
1.62      matthew   118:         $result = 'Unable to find section for this student';
1.37      matthew   119:     } else {
                    120:         $result =~ s/(ok:)+/ok/g;
1.35      matthew   121:     }
                    122:     return $result;
1.10      www       123: }
                    124: 
1.175   ! jms       125: =pod
        !           126: 
        !           127: =item domain_form()
        !           128:     
        !           129:     build a domain and server selection form
        !           130: 
        !           131: =cut
        !           132: 
1.31      matthew   133: sub domain_form {
                    134:     my ($defdom) = @_;
                    135:     # Set up domain and server selection forms
                    136:     #
                    137:     # Get the domains
1.156     albertel  138:     my @domains = &Apache::lonnet::all_domains();
1.31      matthew   139:     # build up the menu information to be passed to 
                    140:     # &Apache::loncommon::linked_select_forms
                    141:     my %select_menus;
                    142:     foreach my $dom (@domains) {
                    143:         # set up the text for this domain
                    144:         $select_menus{$dom}->{'text'}= $dom;
                    145:         # we want a choice of 'default' as the default in the second menu
                    146:         $select_menus{$dom}->{'default'}= 'default';
                    147:         $select_menus{$dom}->{'select2'}->{'default'} = 'default';
                    148:         # Now build up the other items in the second menu
1.157     albertel  149:         my %servers = &Apache::lonnet::get_servers($dom,'library');
1.31      matthew   150:         foreach my $server (keys(%servers)) {
                    151:             $select_menus{$dom}->{'select2'}->{$server} 
                    152:                                             = "$server $servers{$server}";
                    153:         }
                    154:     }
                    155:     my $result  = &Apache::loncommon::linked_select_forms
                    156:         ('studentform',' with home server ',$defdom,
                    157:          'lcdomain','lcserver',\%select_menus);
                    158:     return $result;
                    159: }
                    160: 
1.175   ! jms       161: =pod
        !           162: 
        !           163: =item print_main_menu()
        !           164: 
        !           165:     Menu Phase One
        !           166: 
        !           167: =cut
        !           168: 
1.50      matthew   169: sub print_main_menu {
1.164     albertel  170:     my ($r,$permission)=@_;
1.121     matthew   171:     #
1.150     albertel  172:     my $cid =$env{'request.course.id'};
                    173:     my $cdom=$env{'course.'.$cid.'.domain'};
                    174:     my $cnum=$env{'course.'.$cid.'.num'};
1.121     matthew   175:     my @menu = 
                    176:         ( 
1.122     matthew   177:           { text => 'Upload a class list', 
1.121     matthew   178:             help => 'Course_Create_Class_List',
                    179:             action => 'upload',
1.164     albertel  180:             permission => $permission->{'enrl'},
1.121     matthew   181:             },
                    182:           { text => 'Enroll a single student', 
                    183:             help => 'Course_Add_Student',
                    184:             action => 'enrollstudent',
1.164     albertel  185:             permission => $permission->{'enrl'},
1.121     matthew   186:             },
                    187:           { text => 'Modify student data', 
                    188:             help => 'Course_Modify_Student_Data',
                    189:             action => 'modifystudent',
1.164     albertel  190:             permission => $permission->{'enrl'},
1.121     matthew   191:             },
                    192:           { text => 'View Class List', 
                    193:             help => 'Course_View_Class_List',
                    194:             action => 'classlist',
1.164     albertel  195:             permission => $permission->{'view'},
1.121     matthew   196:             },
                    197:           { text => 'Drop Students', 
                    198:             help => 'Course_Drop_Student',
                    199:             action => 'drop',
1.164     albertel  200:             permission => $permission->{'enrl'},
1.121     matthew   201:             },
                    202:           { text => 'Automated Enrollment Manager', 
1.164     albertel  203:             permission => (&Apache::lonnet::auto_run($cnum,$cdom) 
                    204: 			   && $permission->{'enrl'}),
1.121     matthew   205:             url  => '/adm/populate',
                    206:             },
1.145     albertel  207:           { text => 'Create a new group',
                    208:             help => 'Course_Create_Group',
1.164     albertel  209:             permission => $permission->{'grp_manage'},
1.168     raeburn   210:             url => '/adm/coursegroups?refpage=enrl&amp;action=create',
1.145     albertel  211:             },
                    212:           { text => 'Modify an existing group',
                    213:             help => 'Course_Modify_Group',
1.164     albertel  214:             permission => $permission->{'grp_manage'},
1.168     raeburn   215:             url => '/adm/coursegroups?refpage=enrl&amp;action=modify',
1.145     albertel  216:             },
1.153     raeburn   217:           { text => 'Delete an existing group',
                    218:             help => 'Course_Delete_Group',
1.164     albertel  219:             permission => $permission->{'grp_manage'},
1.168     raeburn   220:             url => '/adm/coursegroups?refpage=enrl&amp;action=delete',
1.153     raeburn   221:             },
                    222:           { text => 'Re-enable a deleted group',
                    223:             help => 'Course_Reenable_Group',
1.164     albertel  224:             permission => $permission->{'grp_manage'},
1.168     raeburn   225:             url => '/adm/coursegroups?refpage=enrl&amp;action=reenable',
1.153     raeburn   226:             },
1.145     albertel  227:           { text => 'Enter an existing group',
                    228:             help => 'Course_Display_Group',
1.164     albertel  229:             permission => $permission->{'grp_view'},
1.168     raeburn   230:             url => '/adm/coursegroups?refpage=enrl&amp;action=view',
1.145     albertel  231:             },
1.121     matthew   232:           );
                    233:     my $menu_html = '';
                    234:     foreach my $menu_item (@menu) {
                    235:         next if (! $menu_item->{'permission'});
                    236:         $menu_html.='<p>';
                    237:         $menu_html.='<font size="+1">';
                    238:         if (exists($menu_item->{'url'})) {
                    239:             $menu_html.=qq{<a href="$menu_item->{'url'}">};
                    240:         } else {
                    241:             $menu_html.=
                    242:                 qq{<a href="/adm/dropadd?action=$menu_item->{'action'}">};
                    243:         }
                    244:         $menu_html.= &mt($menu_item->{'text'}).'</a></font>';
                    245:         if (exists($menu_item->{'help'})) {
                    246:             $menu_html.=
                    247:                 &Apache::loncommon::help_open_topic($menu_item->{'help'});
                    248:         }
                    249:         $menu_html.='</p>'.$/;
1.113     raeburn   250:     }
1.121     matthew   251:     $r->print($menu_html);
                    252:     return;
1.10      www       253: }
                    254: 
1.175   ! jms       255: 
        !           256: 
1.89      matthew   257: sub hidden_input {
                    258:     my ($name,$value) = @_;
                    259:     return '<input type="hidden" name="'.$name.'" value="'.$value.'" />'."\n";
                    260: }
                    261: 
1.175   ! jms       262: 
        !           263: 
1.50      matthew   264: sub print_upload_manager_header {
1.23      albertel  265:     my ($r,$datatoken,$distotal,$krbdefdom)=@_;
1.24      albertel  266:     my $javascript;
1.99      matthew   267:     #
1.127     albertel  268:     if (! exists($env{'form.upfile_associate'})) {
                    269:         $env{'form.upfile_associate'} = 'forward';
1.50      matthew   270:     }
1.127     albertel  271:     if ($env{'form.associate'} eq 'Reverse Association') {
                    272:         if ( $env{'form.upfile_associate'} ne 'reverse' ) {
                    273:             $env{'form.upfile_associate'} = 'reverse';
1.50      matthew   274:         } else {
1.127     albertel  275:             $env{'form.upfile_associate'} = 'forward';
1.50      matthew   276:         }
                    277:     }
1.127     albertel  278:     if ($env{'form.upfile_associate'} eq 'reverse') {
1.50      matthew   279: 	$javascript=&upload_manager_javascript_reverse_associate();
1.24      albertel  280:     } else {
1.50      matthew   281: 	$javascript=&upload_manager_javascript_forward_associate();
1.24      albertel  282:     }
1.99      matthew   283:     #
                    284:     # Deal with restored settings
                    285:     my $password_choice = '';
1.127     albertel  286:     if (exists($env{'form.ipwd_choice'}) &&
                    287:         $env{'form.ipwd_choice'} ne '') {
1.99      matthew   288:         # If a column was specified for password, assume it is for an
                    289:         # internal password.  This is a bug waiting to be filed (could be
                    290:         # local or krb auth instead of internal) but I do not have the 
                    291:         # time to mess around with this now.
                    292:         $password_choice = 'int';        
                    293:     }
                    294:     #
1.171     raeburn   295:     my $javascript_validations = 
                    296:         &javascript_validations('auth',$krbdefdom,$password_choice,undef,
                    297:                                 $env{'request.role.domain'});
1.149     albertel  298:     my $checked=(($env{'form.noFirstLine'})?' checked="checked" ':'');
1.88      matthew   299:     $r->print('<h3>'.&mt('Uploading Class List')."</h3>\n".
                    300:               "<hr>\n".
                    301:               '<h3>'.&mt('Identify fields')."</h3>\n");
                    302:     $r->print("<p>\n".
                    303:               &mt('Total number of records found in file: [_1].',$distotal).
                    304:               "\n".
                    305:               "</p><hr>\n");
1.94      sakharuk  306:     $r->print(&mt('Enter as many fields as you can. The system will inform you and bring you back to this page if the data selected is insufficient to enroll students in your class.')."<hr>\n");
1.89      matthew   307:     $r->print(&hidden_input('action','upload').
                    308:               &hidden_input('state','got_file').
                    309:               &hidden_input('associate','').
                    310:               &hidden_input('datatoken',$datatoken).
1.127     albertel  311:               &hidden_input('fileupload',$env{'form.fileupload'}).
                    312:               &hidden_input('upfiletype',$env{'form.upfiletype'}).
                    313:               &hidden_input('upfile_associate',$env{'form.upfile_associate'}));
1.89      matthew   314:     $r->print('<input type="button" value="Reverse Association" '.
                    315:               'name="'.&mt('Reverse Association').'" '.
                    316:               'onClick="javascript:this.form.associate.value=\'Reverse Association\';submit(this.form);" />');
1.148     banghart  317:     $r->print('<label><input type="checkbox" name="noFirstLine"'.$checked.'/>'.
1.131     albertel  318:               &mt('Ignore First Line').'</label>');
1.89      matthew   319:     $r->print("<hr />\n".
                    320:               '<script type="text/javascript" language="Javascript">'."\n".
                    321:               $javascript."\n".$javascript_validations.'</script>');
1.24      albertel  322: }
                    323: 
1.175   ! jms       324: 
        !           325: 
        !           326: 
        !           327: 
1.24      albertel  328: sub javascript_validations {
1.171     raeburn   329:     my ($mode,$krbdefdom,$curr_authtype,$curr_authfield,$domain)=@_;
1.89      matthew   330:     my $authheader;
                    331:     if ($mode eq 'auth') {
                    332:         my %param = ( formname => 'studentform',
1.99      matthew   333:                       kerb_def_dom => $krbdefdom,
                    334:                       curr_authtype => $curr_authtype);
1.89      matthew   335:         $authheader = &Apache::loncommon::authform_header(%param);
1.91      raeburn   336:     } elsif ($mode eq 'createcourse') {
                    337:         my %param = ( formname => 'ccrs',
1.171     raeburn   338:                       kerb_def_dom => $krbdefdom,
1.99      matthew   339:                       curr_authtype => $curr_authtype );
1.91      raeburn   340:         $authheader = &Apache::loncommon::authform_header(%param);
1.96      raeburn   341:     } elsif ($mode eq 'modifycourse') {
                    342:         my %param = ( formname => 'cmod',
                    343:                   kerb_def_dom => $krbdefdom,
                    344:                   mode => 'modifycourse',
                    345:                   curr_authtype => $curr_authtype,
                    346:                   curr_autharg => $curr_authfield );
                    347:         $authheader = &Apache::loncommon::authform_header(%param);
1.89      matthew   348:     }
1.96      raeburn   349: 
1.91      raeburn   350:     
1.89      matthew   351:     my %alert = &Apache::lonlocal::texthash
                    352:         (username => 'You need to specify the username field.',
                    353:          authen   => 'You must choose an authentication type.',
                    354:          krb      => 'You need to specify the Kerberos domain.',
                    355:          ipass    => 'You need to specify the initial password.',
                    356:          name     => 'The optional name field was not specified.',
                    357:          snum     => 'The optional student number field was not specified.',
1.142     raeburn   358:          section  => 'The optional section field was not specified.', 
1.89      matthew   359:          email    => 'The optional email address field was not specified.',
                    360:          continue => 'Continue enrollment?',
                    361:          );
                    362:     
                    363: #    my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();
                    364:     my $function_name =(<<END);
1.73      www       365: function verify_message (vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail) {
1.89      matthew   366: END
1.171     raeburn   367:     my ($authnum,%can_assign) =  &Apache::loncommon::get_assignable_auth($domain);
1.97      raeburn   368:     my $auth_checks;
1.96      raeburn   369:     if ($mode eq 'createcourse') {
                    370:         $auth_checks .= (<<END);
1.97      raeburn   371:     if (vf.autoadds[0].checked == true) {
1.96      raeburn   372:         if (current.radiovalue == null || current.radiovalue == 'nochange') {
                    373:             alert('$alert{'authen'}');
                    374:             return;
                    375:         }
                    376:     }
                    377: END
                    378:     } else {
1.91      raeburn   379:         $auth_checks .= (<<END);
1.97      raeburn   380:     var foundatype=0;
1.3       www       381:     if (founduname==0) {
1.171     raeburn   382:         alert('$alert{'username'}');
1.3       www       383:         return;
                    384:     }
1.171     raeburn   385: 
                    386: END
                    387:         if ($authnum > 1) {
                    388:             $auth_checks .= (<<END);
1.61      matthew   389:     // alert('current.radiovalue = '+current.radiovalue);
1.119     albertel  390:     if (current.radiovalue == null || current.radiovalue == '' || current.radiovalue == 'nochange') {
1.28      matthew   391:         // They did not check any of the login radiobuttons.
1.89      matthew   392:         alert('$alert{'authen'}');
1.28      matthew   393:         return;
                    394:     }
1.96      raeburn   395: END
1.171     raeburn   396:         }
1.96      raeburn   397:     }
1.97      raeburn   398:     if ($mode eq 'createcourse') {
                    399:         $auth_checks .= "
                    400:     if ( (vf.autoadds[0].checked == true) &&
                    401:          (vf.elements[current.argfield].value == null || vf.elements[current.argfield].value == '') ) {
                    402: ";
                    403:     } elsif ($mode eq 'modifycourse') {
                    404:         $auth_checks .= " 
                    405:     if (vf.elements[current.argfield].value == null || vf.elements[current.argfield].value == '') {
                    406: ";
                    407:     }
1.96      raeburn   408:     if ( ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) {
1.97      raeburn   409:         $auth_checks .= (<<END);
                    410:         var alertmsg = '';
                    411:         switch (current.radiovalue) {
                    412:             case 'krb':
                    413:                 alertmsg = '$alert{'krb'}';
                    414:                 break;
                    415:             default:
                    416:                 alertmsg = '';
1.96      raeburn   417:         }
1.97      raeburn   418:         if (alertmsg != '') {
                    419:             alert(alertmsg);
                    420:             return;
1.96      raeburn   421:         }
                    422:     }
                    423: END
                    424:     } else {
                    425:         $auth_checks .= (<<END);
1.28      matthew   426:     foundatype=1;
1.29      matthew   427:     if (current.argfield == null || current.argfield == '') {
1.28      matthew   428:         var alertmsg = '';
1.29      matthew   429:         switch (current.value) {
1.28      matthew   430:             case 'krb': 
1.89      matthew   431:                 alertmsg = '$alert{'krb'}';
1.28      matthew   432:                 break;
                    433:             case 'loc':
                    434:             case 'fsys':
1.89      matthew   435:                 alertmsg = '$alert{'ipass'}';
1.28      matthew   436:                 break;
                    437:             case 'fsys':
                    438:                 alertmsg = '';
                    439:                 break;
                    440:             default: 
                    441:                 alertmsg = '';
1.3       www       442:         }
1.28      matthew   443:         if (alertmsg != '') {
                    444:             alert(alertmsg);
1.3       www       445:             return;
                    446:         }
                    447:     }
1.89      matthew   448: END
1.96      raeburn   449:     }
1.142     raeburn   450:     my $section_checks;
1.91      raeburn   451:     my $optional_checks = '';
1.96      raeburn   452:     if ( ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) {
1.91      raeburn   453:         $optional_checks = (<<END);
                    454:     vf.submit();
                    455: }
                    456: END
                    457:     } else {
1.173     raeburn   458:         $section_checks = &Apache::lonuserutils::section_check_js();
1.91      raeburn   459:         $optional_checks = (<<END);
1.89      matthew   460:     var message='';
                    461:     if (foundname==0) { 
                    462:         message='$alert{'name'}';
1.24      albertel  463:     }
1.89      matthew   464:     if (foundid==0) { 
                    465:         if (message!='') { 
                    466:             message+='\\n'; 
                    467:         }
                    468:         message+='$alert{'snum'}';
                    469:     }
                    470:     if (foundsec==0) {
                    471:         if (message!='') {
                    472:             message+='\\n';
                    473:         } 
                    474:         message+='$alert{'section'}';
                    475:     }
                    476:     if (foundemail==0) {
                    477:         if (message!='') {
                    478:             message+='\\n';
                    479:         }
                    480:         message+='$alert{'email'}';
1.74      matthew   481:     }
                    482:     if (message!='') {
1.89      matthew   483:         message+= '\\n$alert{'continue'}';
                    484:         if (confirm(message)) {
                    485:             vf.state.value='enrolling';
                    486:             vf.submit();
                    487:         }
1.74      matthew   488:     } else {
1.89      matthew   489:         vf.state.value='enrolling';
                    490:         vf.submit();
1.74      matthew   491:     }
                    492: }
1.89      matthew   493: END
1.91      raeburn   494:     }
1.89      matthew   495:     my $result = $function_name;
1.96      raeburn   496:     if ( ($mode eq 'auth') || ($mode eq 'createcourse') || ($mode eq 'modifycourse')  ) {
1.89      matthew   497:         $result .= $auth_checks;
                    498:     }
1.142     raeburn   499:     $result .= $optional_checks."\n".$section_checks;
1.96      raeburn   500:     if ( ($mode eq 'auth') || ($mode eq 'createcourse') || ($mode eq 'modifycourse')  ) {
1.89      matthew   501:         $result .= $authheader;
                    502:     }
                    503:     return $result;
1.74      matthew   504: }
                    505: 
1.175   ! jms       506: 
        !           507: 
        !           508: 
1.50      matthew   509: sub upload_manager_javascript_forward_associate {
1.24      albertel  510:     return(<<ENDPICK);
1.142     raeburn   511: function verify(vf,sec_caller) {
1.24      albertel  512:     var founduname=0;
                    513:     var foundpwd=0;
                    514:     var foundname=0;
                    515:     var foundid=0;
                    516:     var foundsec=0;
1.73      www       517:     var foundemail=0;
1.24      albertel  518:     var tw;
                    519:     for (i=0;i<=vf.nfields.value;i++) {
                    520:         tw=eval('vf.f'+i+'.selectedIndex');
                    521:         if (tw==1) { founduname=1; }
                    522:         if ((tw>=2) && (tw<=6)) { foundname=1; }
                    523:         if (tw==7) { foundid=1; }
                    524:         if (tw==8) { foundsec=1; }
                    525:         if (tw==9) { foundpwd=1; }
1.73      www       526:         if (tw==10) { foundemail=1; }
1.24      albertel  527:     }
1.73      www       528:     verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail);
1.24      albertel  529: }
                    530: 
1.49      matthew   531: //
                    532: // vf = this.form
                    533: // tf = column number
                    534: //
                    535: // values of nw
                    536: //
                    537: // 0 = none
                    538: // 1 = username
                    539: // 2 = names (lastname, firstnames)
                    540: // 3 = fname (firstname)
                    541: // 4 = mname (middlename)
                    542: // 5 = lname (lastname)
                    543: // 6 = gen   (generation)
                    544: // 7 = id
                    545: // 8 = section
                    546: // 9 = ipwd  (password)
1.73      www       547: // 10 = email address
                    548: 
1.24      albertel  549: function flip(vf,tf) {
                    550:    var nw=eval('vf.f'+tf+'.selectedIndex');
                    551:    var i;
1.49      matthew   552:    // make sure no other columns are labeled the same as this one
1.24      albertel  553:    for (i=0;i<=vf.nfields.value;i++) {
                    554:       if ((i!=tf) && (eval('vf.f'+i+'.selectedIndex')==nw)) {
                    555:           eval('vf.f'+i+'.selectedIndex=0;')
                    556:       }
                    557:    }
1.49      matthew   558:    // If we set this to 'lastname, firstnames', clear out all the ones
                    559:    // set to 'fname','mname','lname','gen' (3,4,5,6) currently.
1.24      albertel  560:    if (nw==2) {
                    561:       for (i=0;i<=vf.nfields.value;i++) {
                    562:          if ((eval('vf.f'+i+'.selectedIndex')>=3) &&
                    563:              (eval('vf.f'+i+'.selectedIndex')<=6)) {
                    564:              eval('vf.f'+i+'.selectedIndex=0;')
                    565:          }
                    566:       }
                    567:    }
1.49      matthew   568:    // If we set this to one of 'fname','mname','lname','gen' (3,4,5,6),
                    569:    // clear out any that are set to 'lastname, firstnames' (2)
1.24      albertel  570:    if ((nw>=3) && (nw<=6)) {
                    571:       for (i=0;i<=vf.nfields.value;i++) {
                    572:          if (eval('vf.f'+i+'.selectedIndex')==2) {
                    573:              eval('vf.f'+i+'.selectedIndex=0;')
                    574:          }
                    575:       }
                    576:    }
1.49      matthew   577:    // If we set the password, make the password form below correspond to 
                    578:    // the new value.
1.24      albertel  579:    if (nw==9) {
1.28      matthew   580:        changed_radio('int',document.studentform);
                    581:        set_auth_radio_buttons('int',document.studentform);
                    582:        vf.intarg.value='';
                    583:        vf.krbarg.value='';
1.24      albertel  584:        vf.locarg.value='';
                    585:    }
                    586: }
                    587: 
                    588: function clearpwd(vf) {
                    589:     var i;
                    590:     for (i=0;i<=vf.nfields.value;i++) {
                    591:         if (eval('vf.f'+i+'.selectedIndex')==9) {
                    592:             eval('vf.f'+i+'.selectedIndex=0;')
                    593:         }
                    594:     }
                    595: }
                    596: 
                    597: ENDPICK
                    598: }
                    599: 
1.175   ! jms       600: 
        !           601: 
        !           602: 
1.50      matthew   603: sub upload_manager_javascript_reverse_associate {
1.24      albertel  604:     return(<<ENDPICK);
1.142     raeburn   605: function verify(vf,sec_caller) {
1.24      albertel  606:     var founduname=0;
                    607:     var foundpwd=0;
                    608:     var foundname=0;
                    609:     var foundid=0;
                    610:     var foundsec=0;
                    611:     var tw;
                    612:     for (i=0;i<=vf.nfields.value;i++) {
                    613:         tw=eval('vf.f'+i+'.selectedIndex');
                    614:         if (i==0 && tw!=0) { founduname=1; }
                    615:         if (((i>=1) && (i<=5)) && tw!=0 ) { foundname=1; }
                    616:         if (i==6 && tw!=0) { foundid=1; }
                    617:         if (i==7 && tw!=0) { foundsec=1; }
                    618:         if (i==8 && tw!=0) { foundpwd=1; }
                    619:     }
                    620:     verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec);
                    621: }
                    622: 
                    623: function flip(vf,tf) {
                    624:    var nw=eval('vf.f'+tf+'.selectedIndex');
                    625:    var i;
                    626:    // picked the all one one name field, reset the other name ones to blank
                    627:    if (tf==1 && nw!=0) {
                    628:       for (i=2;i<=5;i++) {
                    629:          eval('vf.f'+i+'.selectedIndex=0;')
                    630:       }
                    631:    }
                    632:    //picked one of the piecewise name fields, reset the all in
                    633:    //one field to blank
                    634:    if ((tf>=2) && (tf<=5) && (nw!=0)) {
                    635:       eval('vf.f1.selectedIndex=0;')
                    636:    }
                    637:    // intial password specified, pick internal authentication
                    638:    if (tf==8 && nw!=0) {
1.28      matthew   639:        changed_radio('int',document.studentform);
                    640:        set_auth_radio_buttons('int',document.studentform);
                    641:        vf.krbarg.value='';
                    642:        vf.intarg.value='';
1.24      albertel  643:        vf.locarg.value='';
                    644:    }
                    645: }
                    646: 
                    647: function clearpwd(vf) {
                    648:     var i;
                    649:     if (eval('vf.f8.selectedIndex')!=0) {
                    650:         eval('vf.f8.selectedIndex=0;')
                    651:     }
                    652: }
1.2       www       653: ENDPICK
1.23      albertel  654: }
1.10      www       655: 
1.175   ! jms       656: 
        !           657: 
        !           658: 
1.50      matthew   659: sub print_upload_manager_footer {
1.23      albertel  660:     my ($r,$i,$keyfields,$defdom,$today,$halfyear)=@_;
1.64      albertel  661: 
                    662:     my ($krbdef,$krbdefdom) =
                    663:         &Apache::loncommon::get_kerberos_defaults($defdom);
                    664:     my %param = ( formname => 'document.studentform',
                    665:                   kerb_def_dom => $krbdefdom,
                    666:                   kerb_def_auth => $krbdef
                    667:                   );
1.127     albertel  668:     if (exists($env{'form.ipwd_choice'}) &&
                    669:         defined($env{'form.ipwd_choice'}) &&
                    670:         $env{'form.ipwd_choice'} ne '') {
1.99      matthew   671:         $param{'curr_authtype'} = 'int';
                    672:     }
1.28      matthew   673:     my $krbform = &Apache::loncommon::authform_kerberos(%param);
                    674:     my $intform = &Apache::loncommon::authform_internal(%param);
                    675:     my $locform = &Apache::loncommon::authform_local(%param);
1.31      matthew   676:     my $domform = &domain_form($defdom);
1.68      matthew   677:     my $date_table = &date_setting_table();
1.90      matthew   678:     my $Str = "</table>\n";
                    679:     $Str .= &hidden_input('nfields',$i);
                    680:     $Str .= &hidden_input('keyfields',$keyfields);
                    681:     $Str .= '<h3>'.&mt('Login Type')."</h3>\n";
                    682:     $Str .= "<p>\n".
                    683:         &mt('Note: this will not take effect if the user already exists').
1.130     www       684: 	&Apache::loncommon::help_open_topic('Auth_Options').
1.90      matthew   685:         "</p><p>\n";
                    686:     $Str .= $krbform."\n</p><p>\n".
                    687:         $intform."\n</p><p>\n".
                    688:         $locform."\n</p>\n";
                    689:     $Str .= '<h3>'.&mt('LON-CAPA Domain for Students')."</h3>\n";
                    690:     $Str .= "<p>\n".&mt('LON-CAPA domain: [_1]',$domform)."\n</p>\n";
                    691:     $Str .= "<h3>".&mt('Starting and Ending Dates')."</h3>\n";
                    692:     $Str .= "<p>\n".$date_table."</p>\n";
                    693:     $Str .= "<h3>".&mt('Full Update')."</h3>\n";
1.131     albertel  694:     $Str .= '<label><input type="checkbox" name="fullup" value="yes">'.
1.90      matthew   695:         ' '.&mt('Full update (also print list of users not enrolled anymore)').
1.131     albertel  696:         "</label></p>\n";
1.90      matthew   697:     $Str .= "<h3>".&mt('Student Number')."</h3>\n";
1.131     albertel  698:     $Str .= "<p>\n".'<label><input type="checkbox" name="forceid" value="yes">';
1.90      matthew   699:     $Str .= &mt('Disable ID/Student Number Safeguard and Force Change '.
                    700:                 'of Conflicting IDs (only do if you know what you are doing)').
1.131     albertel  701:                 "</label>\n</p><p>\n";
1.142     raeburn   702:     $Str .= '<input type="button"'. 
                    703:               'onClick="javascript:verify(this.form,this.form.csec)" '.
1.95      albertel  704:         'value="Update Class List" />'."<br />\n";
1.90      matthew   705:     $Str .= &mt('Note: for large courses, this operation may be time '.
                    706:                 'consuming');
                    707:     $r->print($Str);
                    708:     return;
1.23      albertel  709: }
1.24      albertel  710: 
1.175   ! jms       711: 
        !           712: 
        !           713: 
1.50      matthew   714: sub print_upload_manager_form {
1.23      albertel  715:     my $r=shift;
1.99      matthew   716: 
1.82      www       717:     my $firstLine;
1.24      albertel  718:     my $datatoken;
1.127     albertel  719:     if (!$env{'form.datatoken'}) {
1.90      matthew   720:         $datatoken=&Apache::loncommon::upfile_store($r);
1.24      albertel  721:     } else {
1.127     albertel  722:         $datatoken=$env{'form.datatoken'};
1.90      matthew   723:         &Apache::loncommon::load_tmp_file($r);
1.24      albertel  724:     }
                    725:     my @records=&Apache::loncommon::upfile_record_sep();
1.127     albertel  726:     if($env{'form.noFirstLine'}){
1.90      matthew   727:         $firstLine=shift(@records);
                    728:     }
1.23      albertel  729:     my $total=$#records;
                    730:     my $distotal=$total+1;
                    731:     my $today=time;
                    732:     my $halfyear=$today+15552000;
1.99      matthew   733:     #
                    734:     # Restore memorized settings
                    735:     &Apache::loncommon::restore_course_settings
                    736:         ('enrollment_upload',{ 'username_choice' => 'scalar', # column settings
                    737:                                'names_choice' => 'scalar',
                    738:                                'fname_choice' => 'scalar',
                    739:                                'mname_choice' => 'scalar',
                    740:                                'lname_choice' => 'scalar',
                    741:                                'gen_choice' => 'scalar',
                    742:                                'id_choice' => 'scalar',
                    743:                                'sec_choice' => 'scalar',
                    744:                                'ipwd_choice' => 'scalar',
                    745:                                'email_choice' => 'scalar',
                    746:                            });
                    747:     #
                    748:     # Determine kerberos parameters as appropriate
1.127     albertel  749:     my $defdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
1.64      albertel  750:     my ($krbdef,$krbdefdom) =
                    751:         &Apache::loncommon::get_kerberos_defaults($defdom);
1.99      matthew   752:     #
1.50      matthew   753:     &print_upload_manager_header($r,$datatoken,$distotal,$krbdefdom);
1.24      albertel  754:     my $i;
                    755:     my $keyfields;
1.23      albertel  756:     if ($total>=0) {
1.99      matthew   757:         my @field=
1.127     albertel  758:             (['username',&mt('Username'),     $env{'form.username_choice'}],
                    759:              ['names',&mt('Last Name, First Names'),$env{'form.names_choice'}],
                    760:              ['fname',&mt('First Name'),      $env{'form.fname_choice'}],
                    761:              ['mname',&mt('Middle Names/Initials'),$env{'form.mname_choice'}],
                    762:              ['lname',&mt('Last Name'),       $env{'form.lname_choice'}],
                    763:              ['gen',  &mt('Generation'),      $env{'form.gen_choice'}],
                    764:              ['id',   &mt('ID/Student Number'),$env{'form.id_choice'}],
1.142     raeburn   765:              ['sec',  &mt('Section'),          $env{'form.sec_choice'}],
1.127     albertel  766:              ['ipwd', &mt('Initial Password'),$env{'form.ipwd_choice'}],
                    767:              ['email',&mt('EMail Address'),   $env{'form.email_choice'}]);
                    768: 	if ($env{'form.upfile_associate'} eq 'reverse') {	
1.24      albertel  769: 	    &Apache::loncommon::csv_print_samples($r,\@records);
1.90      matthew   770: 	    $i=&Apache::loncommon::csv_print_select_table($r,\@records,
                    771:                                                           \@field);
                    772: 	    foreach (@field) { 
                    773:                 $keyfields.=$_->[0].','; 
                    774:             }
1.24      albertel  775: 	    chop($keyfields);
                    776: 	} else {
1.90      matthew   777: 	    unshift(@field,['none','']);
                    778: 	    $i=&Apache::loncommon::csv_samples_select_table($r,\@records,
                    779:                                                             \@field);
1.24      albertel  780: 	    my %sone=&Apache::loncommon::record_sep($records[0]);
                    781: 	    $keyfields=join(',',sort(keys(%sone)));
1.23      albertel  782: 	}
                    783:     }
1.50      matthew   784:     &print_upload_manager_footer($r,$i,$keyfields,$defdom,$today,$halfyear);
1.10      www       785: }
                    786: 
1.175   ! jms       787: 
        !           788: 
        !           789: 
        !           790: 
1.12      www       791: sub enroll_single_student {
1.166     raeburn   792:     my ($r,$srcharray) = @_; 
1.80      matthew   793:     # Remove non alphanumeric values from section
1.127     albertel  794:     $env{'form.csec'}=~s/\W//g;
1.68      matthew   795:     #
                    796:     # We do the dates first because the action of making them the defaul
1.107     www       797:     # in the course is entirely separate from the action of enrolling the
1.68      matthew   798:     # student.  Also, a failure in setting the dates as default is not fatal
                    799:     # to the process of enrolling / modifying a student.
1.173     raeburn   800:     my ($startdate,$enddate) = &Apache::lonuserutils::get_dates_from_form();
1.127     albertel  801:     if ($env{'form.makedatesdefault'}) {
1.173     raeburn   802:         $r->print(&Apache::lonuserutils::make_dates_default($startdate,
                    803:                                                             $enddate));
1.68      matthew   804:     }
                    805: 
1.94      sakharuk  806:     $r->print('<h3>'.&mt('Enrolling Student').'</h3>');
1.162     albertel  807:     $r->print('<p>'.&mt('Enrolling [_1] : [_2]',$env{'form.cuname'},
                    808: 			$env{'form.lcdomain'}).'</p>');
1.150     albertel  809:     if (($env{'form.cuname'})
                    810: 	&& ($env{'form.cuname'} 
                    811: 	    eq &LONCAPA::clean_username($env{'form.cuname'}))
                    812: 	&& ($env{'form.lcdomain'})
                    813: 	&& ($env{'form.lcdomain'}
                    814: 	    eq &LONCAPA::clean_domain($env{'form.lcdomain'}))) {
1.31      matthew   815:         # Deal with home server selection
1.127     albertel  816:         my $domain=$env{'form.lcdomain'};
                    817:         my $desiredhost = $env{'form.lcserver'};
1.31      matthew   818:         if (lc($desiredhost) eq 'default') {
                    819:             $desiredhost = undef;
                    820:         } else {
1.157     albertel  821:             my %home_servers =&Apache::lonnet::get_servers($domain,'library');
1.31      matthew   822:             if (! exists($home_servers{$desiredhost})) {
1.94      sakharuk  823:                 $r->print('<font color="#ff0000">'.&mt('Error').':</font>'.
                    824:                           &mt('Invalid home server specified'));
1.31      matthew   825:                 return;
                    826:             }
                    827:         }
1.94      sakharuk  828:         $r->print(" ".&mt('with server')." $desiredhost :") if (defined($desiredhost));
1.31      matthew   829:         # End of home server selection logic
1.12      www       830: 	my $amode='';
                    831:         my $genpwd='';
1.127     albertel  832:         if ($env{'form.login'} eq 'krb') {
1.47      albertel  833:            $amode='krb';
1.127     albertel  834: 	   $amode.=$env{'form.krbver'};
                    835:            $genpwd=$env{'form.krbarg'};
                    836:         } elsif ($env{'form.login'} eq 'int') {
1.26      matthew   837:            $amode='internal';
1.127     albertel  838:            $genpwd=$env{'form.intarg'};
                    839:         }  elsif ($env{'form.login'} eq 'loc') {
1.15      albertel  840: 	    $amode='localauth';
1.127     albertel  841: 	    $genpwd=$env{'form.locarg'};
1.15      albertel  842: 	    if (!$genpwd) { $genpwd=" "; }
                    843: 	}
1.127     albertel  844:         my $home = &Apache::lonnet::homeserver($env{'form.cuname'},
                    845:                                                    $env{'form.lcdomain'});
1.34      matthew   846:         if ((($amode) && ($genpwd)) || ($home ne 'no_host')) {
1.55      matthew   847:             # Clean out any old roles the student has in this class.
1.173     raeburn   848:             &Apache::lonuserutils::modifystudent($env{'form.lcdomain'},$env{'form.cuname'},
1.127     albertel  849:                            $env{'request.course.id'},$env{'form.csec'},
1.33      matthew   850:                             $desiredhost);
1.55      matthew   851:             my $login_result = &Apache::lonnet::modifystudent
1.127     albertel  852:                 ($env{'form.lcdomain'},$env{'form.cuname'},
                    853:                  $env{'form.cstid'},$amode,$genpwd,
                    854:                  $env{'form.cfirst'},$env{'form.cmiddle'},
                    855:                  $env{'form.clast'},$env{'form.cgen'},
                    856:                  $env{'form.csec'},$enddate,
                    857:                  $startdate,$env{'form.forceid'},
                    858:                  $desiredhost,$env{'form.emailaddress'});
1.55      matthew   859:             if ($login_result =~ /^ok/) {
                    860:                 $r->print($login_result);
1.94      sakharuk  861:                 $r->print("<p> ".&mt('If active, the new role will be available when the student next logs in to LON-CAPA.')."</p>");
1.55      matthew   862:             } else {
1.94      sakharuk  863:                 $r->print(&mt('unable to enroll').": ".$login_result);
1.55      matthew   864:             }
1.12      www       865: 	} else {
1.94      sakharuk  866:             $r->print('<p><font color="#ff0000">'.&mt('ERROR').'</font>&nbsp;');
1.79      matthew   867:             if ($amode =~ /^krb/) {
1.94      sakharuk  868:                 $r->print(&mt('Missing Kerberos domain information.').'  ');
1.79      matthew   869:             } else {
1.94      sakharuk  870:                 $r->print(&mt('Invalid login mode or password.').'  ');
1.79      matthew   871:             }
1.127     albertel  872:             $r->print('<b>'.&mt('Unable to enroll').' '.$env{'form.cuname'}.'.</b></p>');
1.79      matthew   873:         }
1.12      www       874:     } else {
1.94      sakharuk  875:         $r->print(&mt('Invalid username or domain'));
1.26      matthew   876:     }    
1.155     www       877:     $r->print("<p><a href='/adm/dropadd?action=enrollstudent'>".&mt("Enroll another student")."</a></p>");
1.166     raeburn   878:     if (ref($srcharray) eq 'ARRAY') {
                    879:         foreach my $item (@{$srcharray},'ccuname','ccdomain') {
                    880:             $r->print('<input type="hidden" name="'.$item.'" value="'.$env{'form.'.$item}.'" />'."\n");
                    881:         }
                    882:     }
                    883:     foreach my $item ('sortby','seluname','seludom') {
                    884:         if (exists($env{'form.'.$item})) {
                    885:             $r->print('<input type="hidden" name="'.$item.'" value="'.$env{'form.'.$item}.'" />'."\n");
                    886:         }
                    887:     }
                    888:     $r->print('<input type="hidden" name="phase" value="get_user_info" />'."\n".
                    889:               '<input type="hidden" name="currstate" value="" />'."\n".
                    890:               '<input type="hidden" name="prevphase" value="" />'."\n".
                    891:               '<input type="hidden" name="action" value="enrollstudent" />'."\n".
                    892:               '<input type="hidden" name="state" value="gotusername" />');
1.12      www       893: }
                    894: 
1.68      matthew   895: sub setup_date_selectors {
1.91      raeburn   896:     my ($starttime,$endtime,$mode) = @_;
1.68      matthew   897:     if (! defined($starttime)) {
                    898:         $starttime = time;
1.114     raeburn   899:         unless ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') {
1.127     albertel  900:             if (exists($env{'course.'.$env{'request.course.id'}.
1.68      matthew   901:                             '.default_enrollment_start_date'})) {
1.127     albertel  902:                 $starttime = $env{'course.'.$env{'request.course.id'}.
1.68      matthew   903:                                   '.default_enrollment_start_date'};
1.91      raeburn   904:             }
1.68      matthew   905:         }
                    906:     }
                    907:     if (! defined($endtime)) {
                    908:         $endtime = time+(6*30*24*60*60); # 6 months from now, approx
1.91      raeburn   909:         unless ($mode eq 'createcourse') {
1.127     albertel  910:             if (exists($env{'course.'.$env{'request.course.id'}.
1.68      matthew   911:                             '.default_enrollment_end_date'})) {
1.127     albertel  912:                 $endtime = $env{'course.'.$env{'request.course.id'}.
1.68      matthew   913:                                 '.default_enrollment_end_date'};
1.91      raeburn   914:             }
1.68      matthew   915:         }
                    916:     }
                    917:     my $startdateform = &Apache::lonhtmlcommon::date_setter('studentform',
                    918:                                                             'startdate',
                    919:                                                             $starttime);
                    920:     my $enddateform = &Apache::lonhtmlcommon::date_setter('studentform',
                    921:                                                           'enddate',
                    922:                                                           $endtime);
1.114     raeburn   923:     if ($mode eq 'create_enrolldates') {
                    924:         $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs',
                    925:                                                             'startenroll',
                    926:                                                             $starttime);
                    927:         $enddateform = &Apache::lonhtmlcommon::date_setter('ccrs',
                    928:                                                           'endenroll',
                    929:                                                           $endtime);
                    930:     }
                    931:     if ($mode eq 'create_defaultdates') {
1.91      raeburn   932:         $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs',
1.114     raeburn   933:                                                             'startaccess',
1.91      raeburn   934:                                                             $starttime);
                    935:         $enddateform = &Apache::lonhtmlcommon::date_setter('ccrs',
1.114     raeburn   936:                                                           'endaccess',
1.91      raeburn   937:                                                           $endtime);
                    938:     }
1.68      matthew   939:     return ($startdateform,$enddateform);
                    940: }
                    941: 
                    942: sub get_dates_from_form {
                    943:     my $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate');
                    944:     my $enddate   = &Apache::lonhtmlcommon::get_date_from_form('enddate');
1.127     albertel  945:     if ($env{'form.no_end_date'}) {
1.68      matthew   946:         $enddate = 0;
                    947:     }
                    948:     return ($startdate,$enddate);
                    949: }
                    950: 
                    951: sub date_setting_table {
1.91      raeburn   952:     my ($starttime,$endtime,$mode) = @_;
                    953:     my ($startform,$endform)=&setup_date_selectors($starttime,$endtime,$mode);
1.68      matthew   954:     my $dateDefault = '<nobr>'.
1.131     albertel  955:         '<label><input type="checkbox" name="makedatesdefault" /> '.
1.160     albertel  956:         &mt('make these dates the default for future enrollment').
                    957: 	'</label></nobr>';
1.114     raeburn   958:     if ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') {
1.91      raeburn   959:         $dateDefault = '&nbsp;';
                    960:     }
1.131     albertel  961:     my $perpetual = '<nobr><label><input type="checkbox" name="no_end_date"';
1.68      matthew   962:     if (defined($endtime) && $endtime == 0) {
                    963:         $perpetual .= ' checked';
                    964:     }
1.131     albertel  965:     $perpetual.= ' /> '.&mt('no ending date').'</label></nobr>';
1.114     raeburn   966:     if ($mode eq 'create_enrolldates') {
                    967:         $perpetual = '&nbsp;';
                    968:     }
1.68      matthew   969:     my $result = '';
                    970:     $result .= "<table>\n";
1.94      sakharuk  971:     $result .= '<tr><td align="right">'.&mt('Starting Date').'</td>'.
1.68      matthew   972:         '<td>'.$startform.'</td>'.
                    973:         '<td>'.$dateDefault.'</td>'."</tr>\n";
1.94      sakharuk  974:     $result .= '<tr><td align="right">'.&mt('Ending Date').'</td>'.
1.68      matthew   975:         '<td>'.$endform.'</td>'.
                    976:         '<td>'.$perpetual.'</td>'."</tr>\n";
                    977:     $result .= "</table>\n";
                    978:     return $result;
                    979: }
                    980: 
                    981: sub make_dates_default {
                    982:     my ($startdate,$enddate) = @_;
                    983:     my $result = '';
1.127     albertel  984:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                    985:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.68      matthew   986:     my $put_result = &Apache::lonnet::put('environment',
                    987:             {'default_enrollment_start_date'=>$startdate,
                    988:              'default_enrollment_end_date'  =>$enddate},$dom,$crs);
                    989:     if ($put_result eq 'ok') {
                    990:         $result .= "Set default start and end dates for course<br />";
1.69      matthew   991:         #
                    992:         # Refresh the course environment
1.140     albertel  993:         &Apache::lonnet::coursedescription($env{'request.course.id'},
                    994: 					   {'freshen_cache' => 1});
1.68      matthew   995:     } else {
1.94      sakharuk  996:         $result .= &mt('Unable to set default dates for course').":".$put_result.
1.68      matthew   997:             '<br />';
                    998:     }
                    999:     return $result;
                   1000: }
                   1001: 
1.175   ! jms      1002: =pod
        !          1003: 
        !          1004: =item get_student_username_domain_form()
        !          1005:     
        !          1006:     Single student enrollment routines (some of them)
        !          1007: 
        !          1008: =cut
        !          1009: 
1.74      matthew  1010: sub get_student_username_domain_form {
1.166     raeburn  1011:     my ($r,$elements,$response,$srch,$forcenewuser) =  @_;
                   1012:     my $loaditems = {
                   1013:             'onload' => "javascript:setFormElements(document.studentform)",
                   1014:                      };
                   1015:     $r->print(&header(undef,$loaditems));
                   1016:     &Apache::lonhtmlcommon::add_breadcrumb
                   1017:         ({href=>"javascript:backPage(document.studentform,'','')",
                   1018:           text=>"Single user search"});
                   1019:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student',
                   1020:                                                   'Course_Add_Student'));
                   1021:     my $defdom=$env{'request.role.domain'};
                   1022: 
                   1023:     my $jscript = &Apache::loncommon::studentbrowser_javascript()."\n".
                   1024:         '<script type="text/javascript">'."\n".
                   1025:         &Apache::lonhtmlcommon::set_form_elements($elements->{'studentform'}).
                   1026:         '</script>'."\n";
                   1027: 
1.94      sakharuk 1028:     my %lt=&Apache::lonlocal::texthash(
                   1029: 		    'eos'  => "Enroll One Student",
                   1030: 		    'usr'  => "Username",
                   1031:                     'dom'  => "Domain",
                   1032:                     'been' => "Begin Enrollment",
                   1033: 				       );
1.74      matthew  1034:     $r->print(<<END);
1.166     raeburn  1035: $jscript
1.94      sakharuk 1036: <h3>$lt{'eos'}</h3>
1.74      matthew  1037: END
1.169     raeburn  1038:     $r->print($response);
1.166     raeburn  1039:     $r->print(&single_user_entry_form($defdom,$srch,$forcenewuser));
1.74      matthew  1040:     return;
                   1041: }
                   1042: 
1.166     raeburn  1043: sub single_user_entry_form {
                   1044:     my ($dom,$srch,$forcenewuser) = @_;
                   1045:     my $userpicker =
                   1046:        &Apache::loncommon::user_picker($dom,$srch,$forcenewuser,
                   1047:                                        'document.studentform');
                   1048:     my $srchbutton = &mt('Search');
                   1049:     my $output = <<"ENDDOCUMENT";
                   1050: <input type="hidden" name="action" value="enrollstudent" />
                   1051: <input type="hidden" name="state" value="gotusername" />
                   1052: <input type="hidden" name="phase" value="get_user_info" />
                   1053: $userpicker
                   1054: <input name="userrole" type="button" value="$srchbutton" onclick="javascript:validateEntry(document.studentform)" />
                   1055: ENDDOCUMENT
                   1056:     return $output;
                   1057: }
                   1058: 
1.50      matthew  1059: sub print_enroll_single_student_form {
1.166     raeburn  1060:     my ($r,$jscript,$ccuname,$ccdomain,$srch) = @_;
                   1061:     $r->print(&header($jscript));
                   1062:     &Apache::lonhtmlcommon::add_breadcrumb
                   1063:         ({href=>"javascript:backPage(document.studentform,'','')",
                   1064:           text=>"Single user search"});
                   1065:     if ($env{'form.phase'} eq 'userpicked') {
                   1066:         &Apache::lonhtmlcommon::add_breadcrumb
                   1067:      ({href=>"javascript:backPage(document.studentform,'get_user_info','select')",
                   1068:        text=>"Select user",});
                   1069:     }
                   1070:     &Apache::lonhtmlcommon::add_breadcrumb
                   1071:       ({href=>"javascript:backPage(document.studentform,'$env{'form.phase'}','modify')",
                   1072:         text=>"Set enrollment",});
                   1073:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student',
                   1074:                                                   'Course_Add_Student'));
1.94      sakharuk 1075:     $r->print("<h3>".&mt('Enroll One Student')."</h3>");
1.74      matthew  1076:     #
1.166     raeburn  1077:     my $home = &Apache::lonnet::homeserver($ccuname,$ccdomain);
1.74      matthew  1078:     # $new_user flags whether we are creating a new user or using an old one
                   1079:     my $new_user = 1;
                   1080:     if ($home ne 'no_host') {
                   1081:         $new_user = 0;
                   1082:     }
                   1083:     #
                   1084:     my $user_data_html = '';
                   1085:     my $javascript_validations = '';
                   1086:     if ($new_user) {
1.166     raeburn  1087:         my $usertoadd;
                   1088:         my $instsrch = {
                   1089:                          srchin => 'instd',
                   1090:                          srchby => 'uname',
                   1091:                          srchtype => 'exact',
                   1092:                          srchterm => $ccuname,
                   1093:                          srchdomain => $ccdomain,
                   1094:                        };
                   1095:         if (($instsrch->{'srchterm'} ne '') && ($instsrch->{'srchdomain'} ne '')) {
                   1096:             $usertoadd = $instsrch->{'srchterm'}.':'.$instsrch->{'srchdomain'};
                   1097:         }
                   1098:         my (%dirsrch_results,%inst_results);
                   1099:         if ($usertoadd) {
                   1100:             if (&Apache::loncreateuser::directorysrch_check($instsrch) eq 'ok') {
                   1101:                 %dirsrch_results = &Apache::lonnet::inst_directory_query($instsrch);
                   1102:                 if (ref($dirsrch_results{$usertoadd}) eq 'HASH') {
                   1103:                     %inst_results = %{$dirsrch_results{$usertoadd}};
                   1104:                 }
                   1105:             }
                   1106:         }
                   1107: 
1.127     albertel 1108:         my $defdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
1.74      matthew  1109:         # Set up authentication forms
                   1110:         my ($krbdef,$krbdefdom) =
1.166     raeburn  1111:             &Apache::loncommon::get_kerberos_defaults($ccdomain);
1.171     raeburn  1112:         $javascript_validations = 
1.173     raeburn  1113:             &Apache::lonuserutils::javascript_validations('auth',$krbdefdom,
                   1114:                                                       undef,undef,$ccdomain);
1.74      matthew  1115:         my %param = ( formname => 'document.studentform',
                   1116:                       kerb_def_dom => $krbdefdom,
                   1117:                       kerb_def_auth => $krbdef
                   1118:                       );
                   1119:         my $krbform = &Apache::loncommon::authform_kerberos(%param);
                   1120:         my $intform = &Apache::loncommon::authform_internal(%param);
                   1121:         my $locform = &Apache::loncommon::authform_local(%param);
                   1122:         #
                   1123:         # Set up domain selection form
                   1124:         my $homeserver_form = '';
1.166     raeburn  1125:         my %servers = &Apache::lonnet::get_servers($ccdomain,'library');
1.74      matthew  1126:         $homeserver_form = '<select name="lcserver" size="1">'."\n".
                   1127:             '<option value="default" selected>default</option>'."\n";
                   1128:         while (my ($servername,$serverdescription) = each (%servers)) {
                   1129:             $homeserver_form .= '<option value="'.$servername.'">'.
                   1130:                 $serverdescription."</option>\n";
                   1131:         }
                   1132:         $homeserver_form .= "</select>\n";
                   1133:         #
                   1134:         #
1.94      sakharuk 1135: 	my %lt=&Apache::lonlocal::texthash(
1.171     raeburn  1136: 		       'udf'  => "Personal Data",
1.94      sakharuk 1137:                        'fn'   => "First Name",
                   1138:                        'mn'   => "Middle Name",
                   1139:                        'ln'   => "Last Name",
                   1140:                        'gen'  => "Generation",
                   1141:                        'hs'   => "Home Server",
1.171     raeburn  1142:                        'pswd' => "Login Data",
1.94      sakharuk 1143: 		       'psam' => "Please select an authentication mechanism",
1.124     www      1144:                        'mail' => "Email Address"
1.94      sakharuk 1145: 					   );
1.130     www      1146: 	my $authhelp=&Apache::loncommon::help_open_topic('Auth_Options');
1.74      matthew  1147:         $user_data_html = <<END;
1.166     raeburn  1148: <h3>$lt{'udf'} $ccuname:$ccdomain</h3>
1.74      matthew  1149: <table>
1.159     www      1150: <tr><td class="LC_dropadd_labeltext"><label for="cfirst">$lt{'fn'}</label>:</td>
1.166     raeburn  1151:     <td><input type="text" name="cfirst" size="15" value="$inst_results{'firstname'}" /></td></tr>
1.159     www      1152: <tr><td class="LC_dropadd_labeltext"><label for="cmiddle">$lt{'mn'}</label>:</td>
1.166     raeburn  1153:     <td><input type="text" name="cmiddle" size="15" value="$inst_results{'middlename'}" /></td></tr>
1.159     www      1154: <tr><td class="LC_dropadd_labeltext"><label for="clast">$lt{'ln'}</label>:</td>
1.166     raeburn  1155:     <td><input type="text" name="clast" size="15" value="$inst_results{'lastname'}" /></td></tr>
1.159     www      1156: <tr><td class="LC_dropadd_labeltext"><label for="cgen">$lt{'gen'}</label>:</td>
1.166     raeburn  1157:     <td><input type="text" name="cgen" size="5" value="$inst_results{'generation'}" /> </td></tr>
1.159     www      1158: <tr><td class="LC_dropadd_labeltext"><label for="lcserver">$lt{'hs'}</label>:</td>
1.74      matthew  1159:     <td>$homeserver_form</td></tr>
1.159     www      1160: <tr><td class="LC_dropadd_labeltext"><label for="emailaddress">$lt{'mail'}</label>:</td>
1.166     raeburn  1161:     <td><input type="text" name="emailaddress" size="20" value="$inst_results{'permanentemail'}" /></td></tr>
1.74      matthew  1162: </table>
1.94      sakharuk 1163: <h3>$lt{'pswd'}</h3>
1.130     www      1164: $lt{'psam'}$authhelp
1.74      matthew  1165: <p>
                   1166: END
1.171     raeburn  1167:         if ($krbform ne '') {
                   1168:             $user_data_html .= $krbform.'<br />';
                   1169:         }
                   1170:         if ($intform ne '') {
                   1171:             $user_data_html .= $intform.'<br />';
                   1172:         }
                   1173:         if ($locform ne '') {
                   1174:             $user_data_html .= $locform.'<br />';
                   1175:         }
                   1176:         $user_data_html .= "\n</p>\n"
1.74      matthew  1177:     } else {
                   1178:         # User already exists.  Do not worry about authentication
1.166     raeburn  1179:         my %uenv = &Apache::lonnet::dump('environment',$ccdomain,$ccuname);
1.173     raeburn  1180:         $javascript_validations = &Apache::lonuserutils::javascript_validations('noauth');
1.94      sakharuk 1181: 	my %lt=&Apache::lonlocal::texthash(
                   1182: 		       'udf'  => "User Data for",
                   1183:                        'fn'   => "First Name",
                   1184:                        'mn'   => "Middle Name",
                   1185:                        'ln'   => "Last Name",
                   1186:                        'gen'  => "Generation",
1.124     www      1187:                        'mail' => "Email Address",
1.94      sakharuk 1188: 					   );
1.74      matthew  1189:         $user_data_html = <<END;
1.166     raeburn  1190: <h3>$lt{'udf'} $ccuname:$ccdomain</h3>
1.74      matthew  1191: <input type="hidden" name="lcserver" value="default" />
                   1192: <table>
1.159     www      1193: <tr><td class="LC_dropadd_labeltext"><label for="cfirst">$lt{'fn'}</label>:</td>
1.161     raeburn  1194:     <td><input type="text" name="cfirst" value="$uenv{'firstname'}" size="15" /></td></tr>
1.159     www      1195: <tr><td class="LC_dropadd_labeltext"><label for="cmiddle">$lt{'mn'}</label>:</td>
1.161     raeburn  1196:     <td><input type="text" name="cmiddle" value="$uenv{'middlename'}" size="15" /></td></tr>
1.159     www      1197: <tr><td class="LC_dropadd_labeltext"><label for="clast">$lt{'ln'}</label>:</td>
1.161     raeburn  1198:     <td><input type="text" name="clast" value="$uenv{'lastname'}" size="15" /></td></tr>
1.160     albertel 1199: <tr><td class="LC_dropadd_labeltext"><label for="cgen">$lt{'gen'}</label>:</td>
1.161     raeburn  1200:     <td><input type="text" name="cgen" value="$uenv{'generation'}" size="5"  /> </td></tr>
1.160     albertel 1201: <tr><td class="LC_dropadd_labeltext"><label for="emailaddress">$lt{'mail'}</label>:</td>
1.161     raeburn  1202:     <td><input type="text" name="emailaddress" value="$uenv{'permanentemail'}" size="20" /></td></tr>
1.74      matthew  1203: </table>
                   1204: END
                   1205:     }
1.173     raeburn  1206:     my $date_table = &Apache::lonuserutils::date_setting_table();
1.74      matthew  1207:         # Print it all out
1.94      sakharuk 1208:     my %lt=&Apache::lonlocal::texthash(
                   1209: 		   'cd'   => "Course Data",
1.142     raeburn  1210:                    'gs'   => "Section",
1.94      sakharuk 1211:                    'idsn' => "ID/Student Number",
                   1212:                    'disn' => "Disable ID/Student Number Safeguard and Force Change of Conflicting IDs (only do if you know what you are doing)",
                   1213:                    'eas'  => "Enroll as student",
                   1214: 				       );
1.50      matthew  1215:     $r->print(<<END);
1.74      matthew  1216: <input type="hidden" name="action" value="enrollstudent" />
1.166     raeburn  1217: <input type="hidden" name="state"  value="gotusername" />
                   1218: <input type="hidden" name="cuname" value="$ccuname" />
                   1219: <input type="hidden" name="lcdomain" value="$ccdomain" />
1.28      matthew  1220: <script type="text/javascript" language="Javascript">
1.142     raeburn  1221: function verify(vf,sec_caller) {
1.12      www      1222:     var founduname=0;
                   1223:     var foundpwd=0;
                   1224:     var foundname=0;
                   1225:     var foundid=0;
                   1226:     var foundsec=0;
                   1227:     var tw;
1.26      matthew  1228:     if ((typeof(vf.cuname.value) !="undefined") && (vf.cuname.value!='') && 
1.31      matthew  1229: 	(typeof(vf.lcdomain.value)!="undefined") && (vf.lcdomain.value!='')) {
1.12      www      1230:         founduname=1;
                   1231:     }
1.14      harris41 1232:     if ((typeof(vf.cfirst.value)!="undefined") && (vf.cfirst.value!='') &&
1.26      matthew  1233: 	(typeof(vf.clast.value) !="undefined") && (vf.clast.value!='')) {
1.12      www      1234:         foundname=1;
                   1235:     }
1.14      harris41 1236:     if ((typeof(vf.csec.value)!="undefined") && (vf.csec.value!='')) {
1.12      www      1237:         foundsec=1;
1.142     raeburn  1238:         if (validate(sec_caller) == "error") {
                   1239:             return;
                   1240:         }
1.12      www      1241:     }
1.14      harris41 1242:     if ((typeof(vf.cstid.value)!="undefined") && (vf.cstid.value!='')) {
1.12      www      1243: 	foundid=1;
                   1244:     }
                   1245:     if (founduname==0) {
                   1246: 	alert('You need to specify at least the username and domain fields');
                   1247:         return;
                   1248:     }
1.24      albertel 1249:     verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec);
1.12      www      1250: }
                   1251: 
1.24      albertel 1252: $javascript_validations
1.12      www      1253: 
1.24      albertel 1254: function clearpwd(vf) {
                   1255:     //nothing else needs clearing
1.15      albertel 1256: }
                   1257: 
1.12      www      1258: </script>
1.11      www      1259: 
1.74      matthew  1260: $user_data_html
1.50      matthew  1261: 
1.94      sakharuk 1262: <h3>$lt{'cd'}</h3>
1.50      matthew  1263: 
1.159     www      1264: <p><label for="csec">$lt{'gs'}</label>: <input type="text" name="csec" size="5" />
1.160     albertel 1265: </p>
1.68      matthew  1266: $date_table
1.94      sakharuk 1267: <h3>$lt{'idsn'}</h3>
1.50      matthew  1268: <p>
1.160     albertel 1269: <label for="cstid">$lt{'idsn'}</label>: <input type="text" name="cstid" size="10" />
1.26      matthew  1270: </p><p>
1.131     albertel 1271: <label>
1.160     albertel 1272: <input type="checkbox" name="forceid" value="yes" /> 
1.94      sakharuk 1273: $lt{'disn'}
1.131     albertel 1274: </label>
1.50      matthew  1275: </p><p>
1.160     albertel 1276: <input type="button" onClick="verify(this.form,this.form.csec)" value="$lt{'eas'}" />
1.26      matthew  1277: </p>
1.50      matthew  1278: END
1.166     raeburn  1279:     $r->print('<input type="hidden" name="currstate" value="" />'."\n".
                   1280:               '<input type="hidden" name="phase" value="" />'."\n".
                   1281:               '<input type="hidden" name="prevphase" value="'.$env{'form.phase'}.'" />'."\n");
                   1282:     if (ref($srch) eq 'HASH') {
                   1283:         foreach my $item (sort(keys(%{$srch}))) {
                   1284:             $r->print('<input type="hidden" name="'.$item.'" value="'.$srch->{$item}.'" />'."\n");
                   1285:         }
                   1286:     }
                   1287:     foreach my $item ('sortby','seluname','seludom') {
                   1288:         if (exists($env{'form.'.$item})) {
                   1289:             $r->print('<input type="hidden" name="'.$item.'" value="'.$env{'form.'.$item}.'" />'."\n");
                   1290:         }
                   1291:     }
1.50      matthew  1292:     return;
1.10      www      1293: }
                   1294: 
1.175   ! jms      1295: =pod
        !          1296: 
        !          1297: =item print_drop_menu()
        !          1298: 
        !          1299:     Menu Phase Two Drop
        !          1300: 
        !          1301: =cut
        !          1302: 
1.51      matthew  1303: sub print_drop_menu {
1.10      www      1304:     my $r=shift;
1.92      sakharuk 1305:     $r->print("<h3>".&mt('Drop Students')."</h3>");
1.127     albertel 1306:     my $cid=$env{'request.course.id'};
1.56      matthew  1307:     my ($classlist,$keylist) = &Apache::loncoursedata::get_classlist();
                   1308:     if (! defined($classlist)) {
1.94      sakharuk 1309:         $r->print(&mt('There are no students currently enrolled.')."\n");
1.51      matthew  1310:         return;
1.25      matthew  1311:     }
1.51      matthew  1312:     # Print out the available choices
1.56      matthew  1313:     &show_drop_list($r,$classlist,$keylist);
1.51      matthew  1314:     return;
1.11      www      1315: }
                   1316: 
1.175   ! jms      1317: 
        !          1318: =pod
        !          1319: 
        !          1320: =item print_html_classlist()
        !          1321: 
        !          1322:     view classlist
        !          1323: 
        !          1324: =cut
        !          1325: 
1.50      matthew  1326: sub print_html_classlist {
1.164     albertel 1327:     my ($r,$mode,$permission) = @_;
1.127     albertel 1328:     if (! exists($env{'form.sortby'})) {
                   1329:         $env{'form.sortby'} = 'username';
1.57      matthew  1330:     }
1.147     albertel 1331:     if ($env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) {
1.127     albertel 1332:         $env{'form.Status'} = 'Active';
1.57      matthew  1333:     }
                   1334:     my $status_select = &Apache::lonhtmlcommon::StatusOptions
1.127     albertel 1335:         ($env{'form.Status'});
1.150     albertel 1336:     my $cid =$env{'request.course.id'};
1.127     albertel 1337:     my $cdom=$env{'course.'.$cid.'.domain'};
                   1338:     my $cnum=$env{'course.'.$cid.'.num'};
1.103     matthew  1339:     #
                   1340:     # List course personnel
1.100     www      1341:     my %coursepersonnel=&Apache::lonnet::get_course_adv_roles($cdom.'/'.$cnum);
1.110     matthew  1342:     #
1.127     albertel 1343:     if (! defined($env{'form.output'}) ||
                   1344:         $env{'form.output'} !~ /^(csv|excel|html)$/ ) {
                   1345:         $env{'form.output'} = 'html';
1.110     matthew  1346:     }
                   1347:     #
1.139     albertel 1348:     $r->print('<br />'.&Apache::loncommon::start_data_table());
1.110     matthew  1349:     foreach my $role (sort keys %coursepersonnel) {
                   1350:         next if ($role =~ /^\s*$/);
1.139     albertel 1351: 	$r->print(&Apache::loncommon::start_data_table_row().
                   1352: 		  '<td>'.$role.'</td><td>');
1.110     matthew  1353:         foreach my $user (split(',',$coursepersonnel{$role})) {
                   1354: 	    my ($puname,$pudom)=split(':',$user);
1.100     www      1355: 	    $r->print(' '.&Apache::loncommon::aboutmewrapper(
1.110     matthew  1356:                                     &Apache::loncommon::plainname($puname,
                   1357:                                                                   $pudom),
                   1358:                                                              $puname,$pudom));
1.100     www      1359: 	}
1.139     albertel 1360:         $r->print('</td>'.&Apache::loncommon::end_data_table_row());
1.100     www      1361:     }
1.139     albertel 1362:     $r->print(&Apache::loncommon::end_data_table());
1.103     matthew  1363:     #
                   1364:     # Interface output
                   1365:     $r->print('<input type="hidden" name="action" value="'.
1.127     albertel 1366:               $env{'form.action'}.'" />');
1.103     matthew  1367:     $r->print("<p>\n");
1.127     albertel 1368:     if ($env{'form.action'} ne 'modifystudent') {
1.103     matthew  1369: 	my %lt=&Apache::lonlocal::texthash('csv' => "CSV",
                   1370:                                            'excel' => "Excel",
                   1371:                                            'html'  => 'HTML');
1.110     matthew  1372:         my $output_selector = '<select size="1" name="output" >';
1.103     matthew  1373:         foreach my $outputformat ('html','csv','excel') {
                   1374:             my $option = '<option value="'.$outputformat.'" ';
1.127     albertel 1375:             if ($outputformat eq $env{'form.output'}) {
1.104     matthew  1376:                 $option .= 'selected ';
1.103     matthew  1377:             }
                   1378:             $option .='>'.$lt{$outputformat}.'</option>';
                   1379:             $output_selector .= "\n".$option;
                   1380:         }
                   1381:         $output_selector .= '</select>';
1.159     www      1382:         $r->print('<label>'.&mt('Output Format: [_1]',$output_selector).'</label>'.('&nbsp;'x3));
1.59      matthew  1383:     }
1.159     www      1384:     $r->print('<label>'.&mt('Student Status: [_1]',$status_select)."</label>\n");
1.105     matthew  1385:     $r->print('<input type="submit" value="'.&mt('Update Display').'" />'.
                   1386:               "\n</p>\n");
1.103     matthew  1387:     #
                   1388:     # Print the classlist
                   1389:     $r->print('<h2>'.&mt('Current Class List').'</h2>');
1.56      matthew  1390:     my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
1.164     albertel 1391: 
                   1392:     if (exists($permission->{'view_section'})) {
                   1393: 	my $sec = &Apache::loncoursedata::CL_SECTION();	
                   1394: 	foreach my $student (keys(%{$classlist})) {
                   1395: 	    if ($classlist->{$student}[$sec] ne $permission->{'view_section'}) {
                   1396: 		delete($classlist->{$student});
                   1397: 	    }
                   1398: 	}
                   1399:     }
                   1400: 
1.56      matthew  1401:     if (! defined($classlist)) {
1.94      sakharuk 1402:         $r->print(&mt('There are no students currently enrolled.')."\n");
1.40      matthew  1403:     } else {
                   1404:         # Print out the available choices
1.127     albertel 1405:         if ($env{'form.action'} eq 'modifystudent') {
1.110     matthew  1406:             &show_class_list($r,'view','modify',
1.127     albertel 1407:                              $env{'form.Status'},$classlist,$keylist);
1.110     matthew  1408:         } else {
1.127     albertel 1409:             &show_class_list($r,$env{'form.output'},'aboutme',
                   1410:                              $env{'form.Status'},$classlist,$keylist);
1.50      matthew  1411:         }
1.41      matthew  1412:     }
                   1413: }
                   1414: 
1.175   ! jms      1415: 
        !          1416: =pod
        !          1417: 
        !          1418: =item show_class_list()
        !          1419: 
        !          1420:     Show student list to drop
        !          1421: 
        !          1422: =cut
        !          1423: 
1.40      matthew  1424: sub show_class_list {
1.110     matthew  1425:     my ($r,$mode,$linkto,$statusmode,$classlist,$keylist)=@_;
1.127     albertel 1426:     my $cid=$env{'request.course.id'};
1.142     raeburn  1427:     my $cdom = $env{'course.'.$cid.'.domain'};
                   1428:     my $cnum = $env{'course.'.$cid.'.num'};
                   1429:     my ($classgroups) = &Apache::loncoursedata::get_group_memberships(
                   1430:                                               $classlist,$keylist,$cdom,$cnum);
1.60      matthew  1431:     #
                   1432:     # Variables for excel output
1.104     matthew  1433:     my ($excel_workbook, $excel_sheet, $excel_filename,$row,$format);
1.60      matthew  1434:     #
1.103     matthew  1435:     # Variables for csv output
                   1436:     my ($CSVfile,$CSVfilename);
                   1437:     #
1.127     albertel 1438:     my $sortby = $env{'form.sortby'};
1.142     raeburn  1439:     if ($sortby !~ /^(username|domain|section|groups|fullname|id|start|end|type)$/) {
1.53      matthew  1440:         $sortby = 'username';
                   1441:     }
1.134     raeburn  1442:     if (! exists($env{'form.displayphotos'})) {
                   1443:         $env{'form.displayphotos'} = 'off';
                   1444:     }
                   1445:     my $displayphotos = $env{'form.displayphotos'};
                   1446: 
1.170     www      1447:     if (! exists($env{'form.displayclickers'})) {
                   1448:         $env{'form.displayclickers'} = 'off';
                   1449:     }
                   1450:     my $displayclickers = $env{'form.displayclickers'};
                   1451: 
1.42      matthew  1452:     # Print out header 
1.114     raeburn  1453:     unless ($mode eq 'autoenroll') {
                   1454:         $r->print(<<END);
1.127     albertel 1455: <input type="hidden" name="state" value="$env{'form.state'}" />
1.114     raeburn  1456: END
                   1457:     }
1.103     matthew  1458:     $r->print(<<END);
                   1459: <input type="hidden" name="sortby" value="$sortby" />
1.134     raeburn  1460: <input type="hidden" name="displayphotos" value="$displayphotos" />
1.170     www      1461: <input type="hidden" name="displayclickers" value="$displayclickers" />
1.103     matthew  1462: END
1.114     raeburn  1463:     if ($mode eq 'html' || $mode eq 'view' || $mode eq 'autoenroll') {
1.50      matthew  1464:         if ($linkto eq 'aboutme') {
1.142     raeburn  1465:             $r->print(&mt("Select a user name to view the user's personal page."));
1.50      matthew  1466:         } elsif ($linkto eq 'modify') {
1.142     raeburn  1467:             $r->print(&mt("Select a user name to modify the student's information"));
1.50      matthew  1468:         }
1.94      sakharuk 1469: 	my %lt=&Apache::lonlocal::texthash(
1.110     matthew  1470:                                            'usrn'   => "username",
                   1471:                                            'dom'    => "domain",
                   1472:                                            'sn'     => "student name",
                   1473:                                            'sec'    => "section",
1.142     raeburn  1474:                                            'grp'    => "active groups",
1.110     matthew  1475:                                            'start'  => "start date",
                   1476:                                            'end'    => "end date",
1.134     raeburn  1477:                                            'type'   => "enroll type/action",
1.163     albertel 1478: 					   'email'  => "email address",
1.170     www      1479:                                            'clicker'=> "clicker id",
1.134     raeburn  1480:                                            'photo'  => "photo",
1.94      sakharuk 1481: 					   );
1.114     raeburn  1482:         unless ($mode eq 'autoenroll') {
                   1483:             $r->print(<<END);
1.59      matthew  1484: <input type="hidden" name="sname"  value="" />
                   1485: <input type="hidden" name="sdom"   value="" />
1.114     raeburn  1486: END
                   1487:         }
1.136     raeburn  1488:         if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {
1.134     raeburn  1489:             $r->print('
                   1490: <script type="text/javascript">
                   1491: function photowindow(photolink) {
                   1492:     var title = "Photo_Viewer";
                   1493:     var options = "scrollbars=1,resizable=1,menubar=0";
                   1494:     options += ",width=240,height=240";
                   1495:     stdeditbrowser = open(photolink,title,options,"1");
                   1496:     stdeditbrowser.focus();
                   1497: }
                   1498: </script>
                   1499:            ');
                   1500:         }
1.115     raeburn  1501:         $r->print("
1.40      matthew  1502: <p>
1.139     albertel 1503: ".&Apache::loncommon::start_data_table()."
1.115     raeburn  1504: <tr>
                   1505:         ");
                   1506:         if ($mode eq 'autoenroll') {
                   1507:             $r->print("
                   1508:  <th><a href=\"javascript:document.studentform.sortby.value='type';document.studentform.submit();\">$lt{'type'}</a></th>
                   1509:             ");
                   1510:         } else {
                   1511:             $r->print("
                   1512: <th>Count</th>
                   1513:             ");
                   1514:         }
                   1515:         $r->print(<<END);
                   1516:     <th>
1.94      sakharuk 1517:        <a href="javascript:document.studentform.sortby.value='username';document.studentform.submit();">$lt{'usrn'}</a>
1.53      matthew  1518:     </th><th>
1.94      sakharuk 1519:        <a href="javascript:document.studentform.sortby.value='domain';document.studentform.submit();">$lt{'dom'}</a>
1.53      matthew  1520:     </th><th>
1.57      matthew  1521:        <a href="javascript:document.studentform.sortby.value='id';document.studentform.submit();">ID</a>
1.53      matthew  1522:     </th><th>
1.94      sakharuk 1523:        <a href="javascript:document.studentform.sortby.value='fullname';document.studentform.submit();">$lt{'sn'}</a>
1.53      matthew  1524:     </th><th>
1.94      sakharuk 1525:        <a href="javascript:document.studentform.sortby.value='section';document.studentform.submit();">$lt{'sec'}</a>
1.110     matthew  1526:     </th><th>
                   1527:        <a href="javascript:document.studentform.sortby.value='start';document.studentform.submit();">$lt{'start'}</a>
                   1528:     </th><th>
                   1529:        <a href="javascript:document.studentform.sortby.value='end';document.studentform.submit();">$lt{'end'}</a>
1.142     raeburn  1530:     </th><th>
                   1531:        <a href="javascript:document.studentform.sortby.value='groups';document.studentform.submit();">$lt{'grp'}</a>
1.163     albertel 1532:     </th><th>
                   1533:        <a href="javascript:document.studentform.sortby.value='email';document.studentform.submit();">$lt{'email'}</a>
1.53      matthew  1534:     </th>
1.40      matthew  1535: END
1.170     www      1536: 
                   1537: # Clicker display on or off?
                   1538: 
                   1539:         my %clicker_options = &Apache::lonlocal::texthash(
                   1540:                                                           'on' => 'Show',
                   1541:                                                           'off' => 'Hide',
                   1542:                                                          );
                   1543:         my $clickerchg = 'on';
                   1544:         if ($displayclickers eq 'on') {
                   1545:             $clickerchg = 'off';
                   1546:         }
                   1547:         $r->print('    <th>'."\n".'     '.
                   1548:             '<a href="javascript:document.studentform.displayclickers.value='.
                   1549:                       "'".$clickerchg."'".';document.studentform.submit();">'.
                   1550:                       $clicker_options{$clickerchg}.'</a>&nbsp;'.$lt{'clicker'}."\n".
                   1551:                       '    </th>'."\n");
                   1552: 
                   1553: # Photo display on or off?
1.136     raeburn  1554:         if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {
1.135     albertel 1555:             my %photo_options = &Apache::lonlocal::texthash(
1.134     raeburn  1556:                                                             'on' => 'Show',
                   1557:                                                             'off' => 'Hide',
                   1558:                                                             );
                   1559:             my $photochg = 'on';
                   1560:             if ($displayphotos eq 'on') {
                   1561:                 $photochg = 'off';
                   1562:             }
                   1563:             $r->print('    <th>'."\n".'     '. 
                   1564:             '<a href="javascript:document.studentform.displayphotos.value='.
                   1565:                       "'".$photochg."'".';document.studentform.submit();">'.
                   1566:                       $photo_options{$photochg}.'</a>&nbsp;'.$lt{'photo'}."\n".
                   1567:                       '    </th>'."\n");
                   1568:         }
                   1569:         $r->print("  </tr>\n");
1.170     www      1570: 
                   1571: # Done with the HTML header line
                   1572: 
1.41      matthew  1573:     } elsif ($mode eq 'csv') {
1.103     matthew  1574: 	#
                   1575: 	# Open a file
                   1576: 	$CSVfilename = '/prtspool/'.
1.127     albertel 1577: 	    $env{'user.name'}.'_'.$env{'user.domain'}.'_'.
1.103     matthew  1578:             time.'_'.rand(1000000000).'.csv';
                   1579: 	unless ($CSVfile = Apache::File->new('>/home/httpd'.$CSVfilename)) {
                   1580: 	    $r->log_error("Couldn't open $CSVfilename for output $!");
1.174     bisitz   1581: 	    $r->print(&mt('Problems occurred in writing the csv file. '
                   1582:                          .'This error has been logged. '
                   1583:                          .'Please alert your LON-CAPA administrator.'));
1.103     matthew  1584: 	    $CSVfile = undef;
                   1585: 	}
                   1586: 	#
                   1587: 	# Write headers and data to file
1.58      matthew  1588:         if($statusmode eq 'Expired') {
1.103     matthew  1589:             print $CSVfile '"'.&mt('Students with expired roles').'"'."\n";
1.58      matthew  1590:         }
1.147     albertel 1591:         if($statusmode eq 'Future') {
                   1592:             print $CSVfile '"'.&mt('Students with future roles').'"'."\n";
                   1593:         }
1.58      matthew  1594:         if ($statusmode eq 'Any') {
1.103     matthew  1595:             print $CSVfile '"'.join('","',map {
                   1596: 		&Apache::loncommon::csv_translate(&mt($_))
                   1597:                 } ("username","domain","ID","student name",
1.163     albertel 1598:                    "section","start date","end date","status",
                   1599: 		   "active groups","email address"))
1.142     raeburn  1600:                   .'"'."\n";
1.58      matthew  1601:         } else {
1.103     matthew  1602:             print $CSVfile '"'.join('","',map {
                   1603: 		&Apache::loncommon::csv_translate(&mt($_))
                   1604:                 } ("username","domain","ID","student name",
1.163     albertel 1605:                    "section","start date","end date",
                   1606: 		   "active groups","email address")).'"'."\n";
1.58      matthew  1607:         }
1.60      matthew  1608:     } elsif ($mode eq 'excel') {
                   1609:         # Create the excel spreadsheet
1.126     matthew  1610:         ($excel_workbook,$excel_filename,$format) = 
                   1611:             &Apache::loncommon::create_workbook($r);
                   1612:         return if (! defined($excel_workbook));
1.60      matthew  1613:         $excel_sheet = $excel_workbook->addworksheet('classlist');
                   1614:         #
1.76      albertel 1615:         my $description = 'Class List for '.
1.127     albertel 1616:             $env{'course.'.$env{'request.course.id'}.'.description'};
1.104     matthew  1617:         $excel_sheet->write($row++,0,$description,$format->{'h1'});
1.60      matthew  1618:         #
                   1619:         $excel_sheet->write($row++,0,["username","domain","ID",
1.110     matthew  1620:                                       "student name","section",
1.142     raeburn  1621:                                       "start date","end date","status",
1.163     albertel 1622:                                       "active groups","email address"],
1.110     matthew  1623:                             $format->{'bold'});
1.41      matthew  1624:     }
1.170     www      1625: 
                   1626: # Done with header lines in all formats
                   1627: 
1.56      matthew  1628:     #
                   1629:     # Sort the students
                   1630:     my %index;
                   1631:     my $i;
                   1632:     foreach (@$keylist) {
                   1633:         $index{$_} = $i++;
                   1634:     }
1.142     raeburn  1635:     $index{'groups'} = scalar(@{$keylist});
1.56      matthew  1636:     my $index  = $index{$sortby};
                   1637:     my $second = $index{'username'};
                   1638:     my $third  = $index{'domain'};
1.53      matthew  1639:     my @Sorted_Students = sort {
1.56      matthew  1640:         lc($classlist->{$a}->[$index])  cmp lc($classlist->{$b}->[$index])
                   1641:             ||
                   1642:         lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
                   1643:             ||
                   1644:         lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
                   1645:         } (keys(%$classlist));
1.108     matthew  1646:     my $studentcount = 0;
1.115     raeburn  1647:     my $autocount = 0;
                   1648:     my $manualcount = 0;
                   1649:     my $unlockcount = 0;
                   1650:     my $lockcount = 0;
1.53      matthew  1651:     foreach my $student (@Sorted_Students) {
1.110     matthew  1652:         my $sdata = $classlist->{$student};
1.142     raeburn  1653:         my $groups = $classgroups->{$student};
1.110     matthew  1654:         my $username = $sdata->[$index{'username'}];
                   1655:         my $domain   = $sdata->[$index{'domain'}];
                   1656:         my $section  = $sdata->[$index{'section'}];
1.142     raeburn  1657:         my $active_groups;
                   1658:         if (ref($groups->{active}) eq 'HASH') {
                   1659:             $active_groups = join(', ',keys(%{$groups->{'active'}}));
                   1660:         }
1.110     matthew  1661:         my $name     = $sdata->[$index{'fullname'}];
                   1662:         my $id       = $sdata->[$index{'id'}];
                   1663:         my $status   = $sdata->[$index{'status'}];
1.163     albertel 1664:         next if (($statusmode ne 'Any') && ($status ne $statusmode));
1.110     matthew  1665:         my $start    = $sdata->[$index{'start'}];
                   1666:         my $end      = $sdata->[$index{'end'}];
1.115     raeburn  1667:         my $type     = $sdata->[$index{'type'}];
1.163     albertel 1668: 
                   1669: 	my %emails   = &Apache::loncommon::getemails($username,$domain);
                   1670: 	my $email;
1.168     raeburn  1671: 	if ($emails{'permanentemail'} =~ /\S/) {
                   1672: 	    $email = $emails{'permanentemail'};
1.163     albertel 1673: 	}
                   1674: 
1.114     raeburn  1675:         if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') {
                   1676:             if (! defined($start) || $start == 0) {
                   1677:                 $start = &mt('none');
                   1678:             } else {
                   1679:                 $start = &Apache::lonlocal::locallocaltime($start);
                   1680:             }
                   1681:             if (! defined($end) || $end == 0) {
                   1682:                 $end = &mt('none');
                   1683:             } else {
                   1684:                 $end = &Apache::lonlocal::locallocaltime($end);
                   1685:             }
1.139     albertel 1686: 	    $r->print(&Apache::loncommon::start_data_table_row());
1.115     raeburn  1687:             if ($mode eq 'autoenroll') {
                   1688:                 my $lockedtype = $sdata->[$index{'lockedtype'}];
                   1689:                 $studentcount++;
                   1690:                 my $cellentry;
                   1691:                 if ($type eq 'auto') {
1.131     albertel 1692:                     $cellentry = '<b>'.&mt('auto').'</b>&nbsp;<label><input type="checkbox" name="chgauto" value="'.$username.':'.$domain.'" />&nbsp;Change</label>';
1.115     raeburn  1693:                     $autocount ++;
                   1694:                 } else {
1.131     albertel 1695:                     $cellentry = '<table border="0" cellspacing="0"><tr><td rowspan="2"><b>'.&mt('manual').'</b></td><td><nobr><label><input type="checkbox" name="chgmanual" value="'.$username.':'.$domain.'" />&nbsp;Change</label></nobr></td></tr><tr><td><nobr>';
1.115     raeburn  1696:                     $manualcount ++;
                   1697:                     if ($lockedtype) {
1.131     albertel 1698:                         $cellentry .= '<label><input type="checkbox" name="unlockchg" value="'.$username.':'.$domain.'" />&nbsp;'.&mt('Unlock').'</label>';
1.115     raeburn  1699:                         $unlockcount ++;
                   1700:                     } else {
1.131     albertel 1701:                         $cellentry .= '<label><input type="checkbox" name="lockchg" value="'.$username.':'.$domain.'" />&nbsp;'.&mt('Lock').'</label>';
1.115     raeburn  1702:                         $lockcount ++;
                   1703:                     }
1.118     raeburn  1704:                     $cellentry .= '</nobr></td></tr></table>';
1.115     raeburn  1705:                 }
                   1706:                 $r->print("<td>$cellentry<td>\n    ");
                   1707:             } else {
                   1708:                 $r->print("<td>".(++$studentcount)."</td><td>\n    ");
                   1709:             }
1.51      matthew  1710:             if ($linkto eq 'nothing') {
                   1711:                 $r->print($username);
                   1712:             } elsif ($linkto eq 'aboutme') {
                   1713:                 $r->print(&Apache::loncommon::aboutmewrapper($username,
                   1714:                                                              $username,
                   1715:                                                              $domain));
                   1716:             } elsif ($linkto eq 'modify') {
1.59      matthew  1717:                 $r->print('<a href="'.
                   1718:                           "javascript:document.studentform.sname.value='".
                   1719:                           $username.
                   1720:                           "';document.studentform.sdom.value='".$domain.
                   1721:                           "';document.studentform.state.value='selected".
                   1722:                           "';document.studentform.submit();".'">'.
1.53      matthew  1723:                           $username."</a>\n");
1.50      matthew  1724:             }
1.51      matthew  1725:             $r->print(<<"END");
1.50      matthew  1726:     </td>
1.51      matthew  1727:     <td>$domain</td>
                   1728:     <td>$id</td>
                   1729:     <td>$name</td>
                   1730:     <td>$section</td>
1.110     matthew  1731:     <td>$start</td>
                   1732:     <td>$end</td>
1.142     raeburn  1733:     <td>$active_groups</td>
1.163     albertel 1734:     <td>$email</td>
1.114     raeburn  1735: END
1.170     www      1736: 
                   1737: # Clickers
                   1738:             if ($displayclickers eq 'on') {
                   1739:                my $clickers =
                   1740:                (&Apache::lonnet::userenvironment($domain,$username,'clickers'))[1];
                   1741:                if ($clickers!~/\w/) { $clickers='-'; }
                   1742:                $r->print('<td>'.$clickers.'</td>');
                   1743:             } else {
                   1744:                 $r->print('    <td>&nbsp;</td>  ');
                   1745:             }
                   1746: 
                   1747: # Photos
                   1748: 
1.134     raeburn  1749:             if ($env{'course.'.$env{'request.course.id'}.
1.136     raeburn  1750: 			 '.internal.showphoto'}) {
1.134     raeburn  1751:                 if ($displayphotos eq 'on') {
1.135     albertel 1752:                     my $imgurl = 
                   1753: 			&Apache::lonnet::retrievestudentphoto($domain,
                   1754: 							      $username,'gif',
                   1755: 							      'thumbnail');
1.134     raeburn  1756:                 
                   1757:                     $r->print('    <td align="right"><a href="javascript:photowindow('."'".&Apache::lonnet::studentphoto($domain,$username,'jpg')."'".')"><img src="'.$imgurl.'" border="1"></a></td>');
                   1758:                 } else {
                   1759:                     $r->print('    <td>&nbsp;</td>  ');
                   1760:                 }
                   1761:             }
1.139     albertel 1762: 	    $r->print(&Apache::loncommon::end_data_table_row());
1.51      matthew  1763:         } elsif ($mode eq 'csv') {
1.103     matthew  1764:             next if (! defined($CSVfile));
1.51      matthew  1765:             # no need to bother with $linkto
1.114     raeburn  1766:             if (! defined($start) || $start == 0) {
                   1767:                 $start = &mt('none');
                   1768:             } else {
                   1769:                 $start = &Apache::lonlocal::locallocaltime($start);
                   1770:             }
                   1771:             if (! defined($end) || $end == 0) {
                   1772:                 $end = &mt('none');
                   1773:             } else {
                   1774:                 $end = &Apache::lonlocal::locallocaltime($end);
                   1775:             }
1.51      matthew  1776:             my @line = ();
1.110     matthew  1777:             foreach ($username,$domain,$id,$name,$section,$start,$end) {
1.51      matthew  1778:                 push @line,&Apache::loncommon::csv_translate($_);
1.58      matthew  1779:             }
                   1780:             if ($statusmode eq 'Any') {
                   1781:                 push @line,&Apache::loncommon::csv_translate($status);
1.41      matthew  1782:             }
1.142     raeburn  1783:             push @line,&Apache::loncommon::csv_translate($active_groups);
1.163     albertel 1784:             push @line,&Apache::loncommon::csv_translate($email);
1.103     matthew  1785:             print $CSVfile '"'.join('","',@line).'"'."\n";
1.60      matthew  1786:         } elsif ($mode eq 'excel') {
1.110     matthew  1787:             $excel_sheet->write($row,0,[$username,$domain,$id,
                   1788:                                           $name,$section]);
                   1789:             my $col = 5;
                   1790:             foreach my $time ($start,$end) {
1.129     matthew  1791:                 if (defined($time) && $time != 0) {
                   1792:                     $excel_sheet->write($row,$col++,
1.110     matthew  1793:                                    &Apache::lonstathelpers::calc_serial($time),
                   1794:                                     $format->{'date'});
1.129     matthew  1795:                 } else {
                   1796:                     $excel_sheet->write($row,$col++,'none');
                   1797:                 }                    
1.110     matthew  1798:             }
                   1799:             $excel_sheet->write($row,$col++,$status);
1.142     raeburn  1800:             $excel_sheet->write($row,$col++,$active_groups);
1.163     albertel 1801:             $excel_sheet->write($row,$col++,$email);
1.110     matthew  1802:             $row++;
1.40      matthew  1803:         }
                   1804:     }
1.114     raeburn  1805:     if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') {
1.139     albertel 1806: 	$r->print(&Apache::loncommon::end_data_table().'<br />');
1.60      matthew  1807:     } elsif ($mode eq 'excel') {
                   1808:         $excel_workbook->close();
                   1809:         $r->print('<p><a href="'.$excel_filename.'">'.
1.94      sakharuk 1810:                   &mt('Your Excel spreadsheet').'</a> '.&mt('is ready for download').'.</p>'."\n");
1.103     matthew  1811:     } elsif ($mode eq 'csv') {
                   1812:         close($CSVfile);
                   1813:         $r->print('<a href="'.$CSVfilename.'">'.
                   1814:                   &mt('Your CSV file').'</a> is ready for download.'.
                   1815:                   "\n");
                   1816:         $r->rflush();
1.60      matthew  1817:     }
1.114     raeburn  1818:     if ($mode eq 'autoenroll') {
1.115     raeburn  1819:         return ($studentcount,$autocount,$manualcount,$lockcount,$unlockcount);
1.114     raeburn  1820:     }
1.115     raeburn  1821:     return;
1.40      matthew  1822: }
                   1823: 
1.50      matthew  1824: 
1.175   ! jms      1825: =pod
        !          1826: 
        !          1827: =item print_modify_student_form()
        !          1828: 
        !          1829:     print out form for modification of a single students data
        !          1830: 
        !          1831: =cut
        !          1832: 
1.50      matthew  1833: sub print_modify_student_form {
                   1834:     my $r = shift();
                   1835:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.59      matthew  1836:                                             ['sdom','sname']);    
1.127     albertel 1837:     my $sname  = $env{'form.sname'};
                   1838:     my $sdom   = $env{'form.sdom'};
                   1839:     my $sortby = $env{'form.sortby'};
1.50      matthew  1840:     # determine the students name information
                   1841:     my %info=&Apache::lonnet::get('environment',
                   1842:                                   ['firstname','middlename',
1.168     raeburn  1843:                                    'lastname','generation','id',
                   1844:                                    'permanentemail'], $sdom, $sname);
1.50      matthew  1845:     my ($tmp) = keys(%info);
                   1846:     if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.94      sakharuk 1847:         $r->print('<font color="#ff0000" size="+2">'.&mt('Error').'</font>'.
1.50      matthew  1848:                   '<p>'.
1.94      sakharuk 1849:                   &mt('Unable to retrieve environment data for').' '.$sname.
                   1850:                   &mt('in domain').' '.$sdom.'</p><p>'.
1.138     albertel 1851:                   &mt('Please contact your LON-CAPA administrator regarding this situation.').'</p>'.&Apache::loncommon::end_page());
1.50      matthew  1852:         return;
                   1853:     }
                   1854:     # determine the students starting and ending times and section
                   1855:     my ($starttime,$endtime,$section) = &get_enrollment_data($sname,$sdom);
1.87      matthew  1856:     if ($starttime =~ /^error/) {
1.94      sakharuk 1857:         $r->print('<h2>'&mt('Error').'</h2>');
1.87      matthew  1858:         $r->print('<p>'.$starttime.'</p>');
                   1859:         return;
                   1860:     }
1.101     matthew  1861:     #
1.50      matthew  1862:     # Deal with date forms
1.101     matthew  1863:     my $current_date_description = '';
                   1864:     my $textdate = '';
                   1865: 
                   1866:     if (! defined($starttime) || $starttime == 0) {
                   1867:         $current_date_description = &mt('Current Starting Date: not set').
                   1868:             '<br />';
                   1869:     } else {
                   1870:         $current_date_description = 
                   1871:             &mt('Current Starting Date: [_1]',
                   1872:                 &Apache::lonlocal::locallocaltime($starttime)).'<br />';
                   1873:     }
                   1874:     if (! defined($endtime) || $endtime == 0) {
                   1875:         $current_date_description.= &mt('Current Ending Date: not set').
                   1876:             '<br />';
                   1877:     } else {
                   1878:         $current_date_description.= 
                   1879:             &mt('Current Ending Date: [_1]',
                   1880:                 &Apache::lonlocal::locallocaltime($endtime)).'<br />';
                   1881: 
                   1882:     }
1.173     raeburn  1883:     my $date_table = 
                   1884:         &Apache::lonuserutils::date_setting_table($starttime,$endtime);
1.59      matthew  1885:     #
1.127     albertel 1886:     if (! exists($env{'form.Status'}) || 
1.147     albertel 1887:         $env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) {
1.127     albertel 1888:         $env{'form.Status'} = 'crap';
1.59      matthew  1889:     }
1.94      sakharuk 1890:     # Make sure student is enrolled in course
                   1891:     my %lt=&Apache::lonlocal::texthash(
                   1892: 	           'mef'   => "Modify Enrollment for",
                   1893:                    'odcc'  => "Only domain coordinators can change a users password.",
                   1894:                    'sn'    => "Student Name",
                   1895:                    'fn'    => "First",
                   1896:                    'mn'    => "Middle",
                   1897:                    'ln'    => "Last",
                   1898:                    'gen'   => "Generation",
1.168     raeburn  1899:                    'email' => "E-mail address",
1.94      sakharuk 1900:                    'sid'   => "Student ID",
                   1901:                    'disn'  => "Disable ID/Student Number Safeguard and Force Change of Conflicting IDs (only do if you know what you are doing)",
                   1902:                    'sec'   => "Section",
                   1903:                    'sm'    => "Submit Modifications",
                   1904: 				       );
1.142     raeburn  1905: # Check if section name is valid
1.173     raeburn  1906:     my $section_check = &Apache::lonuserutils::section_check_js();
1.142     raeburn  1907:     $r->print(<<"END");
                   1908: <script type="text/javascript">
                   1909: $section_check
                   1910: function secverify(formname,caller) {
                   1911:     if (validate(caller) == "error") {
                   1912:         return;
                   1913:     } else {
                   1914:         formname.submit();
                   1915:     }
                   1916: }
                   1917: </script>
1.52      matthew  1918: <p>
                   1919: <font size="+1">
1.94      sakharuk 1920: $lt{'odcc'}
1.52      matthew  1921: </font>
                   1922: </p>
1.50      matthew  1923: <input type="hidden" name="slogin"  value="$sname"  />
                   1924: <input type="hidden" name="sdomain" value="$sdom" />
                   1925: <input type="hidden" name="action"  value="modifystudent" />
1.53      matthew  1926: <input type="hidden" name="state"   value="done" />
                   1927: <input type="hidden" name="sortby"  value="$sortby" />
1.127     albertel 1928: <input type="hidden" name="Status"  value="$env{'form.Status'}" />
1.168     raeburn  1929: <h3>$lt{'mef'} $info{'firstname'} $info{'middlename'} 
                   1930: $info{'lastname'} $info{'generation'}, $sname:$sdom</h3>
1.50      matthew  1931: <p>
1.94      sakharuk 1932: <b>$lt{'sn'}</b>
1.50      matthew  1933: <table>
1.94      sakharuk 1934: <tr><th>$lt{'fn'}</th><th>$lt{'mn'}</th><th>$lt{'ln'}</th><th>$lt{'gen'}</th></tr>
1.50      matthew  1935: <tr><td>
                   1936: <input type="text" name="firstname"  value="$info{'firstname'}"  /></td><td>
                   1937: <input type="text" name="middlename" value="$info{'middlename'}" /></td><td>
                   1938: <input type="text" name="lastname"   value="$info{'lastname'}"   /></td><td>
                   1939: <input type="text" name="generation" value="$info{'generation'}" /></td></tr>
                   1940: </table>
                   1941: </p><p>
1.168     raeburn  1942: <b>$lt{'email'}</b>: <input type="text" name="permanentemail" value="$info{'permanentemail'}" size="30" />
                   1943: </p><p>
1.160     albertel 1944: <b>$lt{'sid'}</b>: <input type="text" name="id" value="$info{'id'}" size="12" />
1.52      matthew  1945: </p><p>
1.131     albertel 1946: <label>
1.160     albertel 1947: <input type="checkbox" name="forceid" /> 
1.94      sakharuk 1948: $lt{'disn'}
1.131     albertel 1949: </label>
1.53      matthew  1950: </p><p>
1.160     albertel 1951: <b>$lt{'sec'}</b>: <input type="text" name="section" value="$section" size="14" />
1.50      matthew  1952: </p>
1.101     matthew  1953: <p>$current_date_description</p>
1.68      matthew  1954: <p>$date_table</p>
1.142     raeburn  1955: <input type="button" value="$lt{'sm'}" onClick="secverify(this.form,this.form.section)" />
1.50      matthew  1956: END
1.138     albertel 1957:     $r->print(&Apache::loncommon::end_page());
1.50      matthew  1958:     return;
                   1959: }
                   1960: 
1.175   ! jms      1961: 
        !          1962: =pod 
        !          1963: 
        !          1964: =item modify_single_student()
        !          1965: 
        !          1966:     modify a single students section 
        !          1967: 
        !          1968: =cut
        !          1969: 
1.50      matthew  1970: sub modify_single_student {
1.138     albertel 1971:     my ($r) = @_;
1.68      matthew  1972:     #
1.80      matthew  1973:     # Remove non alphanumeric values from the section
1.127     albertel 1974:     $env{'form.section'} =~ s/\W//g;
1.77      matthew  1975:     #
1.68      matthew  1976:     # Do the date defaults first
1.173     raeburn  1977:     my ($starttime,$endtime) = &Apache::lonuserutils::get_dates_from_form();
1.127     albertel 1978:     if ($env{'form.makedatesdefault'}) {
1.173     raeburn  1979:         $r->print(&Apache::lonuserutils::make_dates_default($starttime,
                   1980:                                                             $endtime));
1.68      matthew  1981:     }
1.59      matthew  1982:     # Get the 'sortby' and 'Status' variables so the user goes back to their
                   1983:     # previous screen
1.127     albertel 1984:     my $sortby = $env{'form.sortby'};
                   1985:     my $status = $env{'form.Status'};
1.53      matthew  1986:     #
                   1987:     # We always need this information
1.127     albertel 1988:     my $slogin     = $env{'form.slogin'};
                   1989:     my $sdom       = $env{'form.sdomain'};
1.53      matthew  1990:     #
                   1991:     # Get the old data
                   1992:     my %old=&Apache::lonnet::get('environment',
                   1993:                                  ['firstname','middlename',
1.168     raeburn  1994:                                   'lastname','generation','id',
                   1995:                                   'permanentemail'],$sdom, $slogin);
1.59      matthew  1996:     $old{'section'} = &Apache::lonnet::getsection($sdom,$slogin,
1.127     albertel 1997:                                                   $env{'request.course.id'});
1.53      matthew  1998:     my ($tmp) = keys(%old);
                   1999:     if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.162     albertel 2000:         $r->print(&mt('There was an error determining the environment values for')." $slogin : $sdom.");
1.53      matthew  2001:         return;
                   2002:     }
                   2003:     undef $tmp;
                   2004:     #
                   2005:     # Get the new data
1.127     albertel 2006:     my $firstname  = $env{'form.firstname'};
                   2007:     my $middlename = $env{'form.middlename'};
                   2008:     my $lastname   = $env{'form.lastname'};
                   2009:     my $generation = $env{'form.generation'};
1.168     raeburn  2010:     my $permanentemail = $env{'form.permanentemail'};
1.127     albertel 2011:     my $section    = $env{'form.section'};
                   2012:     my $courseid   = $env{'request.course.id'};
                   2013:     my $sid        = $env{'form.id'};
1.50      matthew  2014:     my $displayable_starttime = localtime($starttime);
                   2015:     my $displayable_endtime   = localtime($endtime);
1.53      matthew  2016:     # 
                   2017:     # check for forceid override
1.63      matthew  2018:     if ((defined($old{'id'})) && ($old{'id'} ne '') && 
1.127     albertel 2019:         ($sid ne $old{'id'}) && (! exists($env{'form.forceid'}))) {
1.94      sakharuk 2020:         $r->print("<font color=\"ff0000\">".&mt('You changed the students id but did not disable the ID change safeguard. The students id will not be changed.')."</font>");
1.53      matthew  2021:         $sid = $old{'id'};
                   2022:     }
                   2023:     #
1.50      matthew  2024:     # talk to the user about what we are going to do
1.94      sakharuk 2025:     my %lt=&Apache::lonlocal::texthash(
                   2026: 	           'mdu'   => "Modifying data for user",
                   2027:                    'si'    => "Student Information",
                   2028:                    'fd'    => "Field",
                   2029:                    'ov'    => "Old Value",
                   2030:                    'nv'    => "New Value",
                   2031:                    'fn'    => "First name",
                   2032:                    'mn'    => "Middle name",
                   2033:                    'ln'    => "Last name",
                   2034:                    'gen'   => "Generation",
1.168     raeburn  2035:                    'em'    => "E-mail address",
1.94      sakharuk 2036:                    'sec'   => "Section",
                   2037:                    'ri'    => "Role Information",
                   2038:                    'st'    => "Start Time",
                   2039:                    'et'    => "End Time",
                   2040: 				       );
1.50      matthew  2041:     $r->print(<<END);
1.168     raeburn  2042:     <h3>$lt{'mdu'} $slogin:$sdom </h3>
                   2043: END
                   2044:     $r->print(<<END);
1.50      matthew  2045: <table>
1.168     raeburn  2046:  <tr>
                   2047:   <td>
                   2048:     <table class="LC_nested_outer">
                   2049:      <tr>
                   2050:       <th>$lt{si}</th>
                   2051:      </tr>
                   2052:      <tr>
                   2053:       <td>
                   2054:        <table class="LC_nested">
                   2055:         <tr class="LC_info_row">
                   2056:          <td class="LC_left_item"> $lt{'fd'} </td>
                   2057:          <td class="LC_left_item"> $lt{'ov'} </td>
                   2058:          <td class="LC_left_item"> $lt{'nv'} </td>
                   2059:         </tr>
                   2060:         <tr class="LC_odd_row">
                   2061:          <td class="LC_left_item"> <b>$lt{'fn'}</b> </td>
                   2062:          <td class="LC_left_item"> $old{'firstname'} </td>
                   2063:          <td class="LC_left_item"> $firstname </td>
                   2064:         </tr>
                   2065:         <tr>
                   2066:          <td class="LC_left_item"> <b>$lt{'mn'}</b> </td>
                   2067:          <td class="LC_left_item"> $old{'middlename'} </td>
                   2068:          <td class="LC_left_item"> $middlename </td>
                   2069:         </tr>
                   2070:         <tr class="LC_odd_row">
                   2071:          <td class="LC_left_item"> <b>$lt{'ln'}</b> </td>
                   2072:          <td class="LC_left_item"> $old{'lastname'} </td>
                   2073:          <td class="LC_left_item"> $lastname </td>
                   2074:         </tr>
                   2075:         <tr>
                   2076:          <td class="LC_left_item"> <b>$lt{'gen'}</b> </td>
                   2077:          <td class="LC_left_item"> $old{'generation'} </td>
                   2078:          <td class="LC_left_item"> $generation </td>
                   2079:         </tr>
                   2080:         <tr class="LC_odd_row">
                   2081:          <td class="LC_left_item"> <b>ID</b> </td>
                   2082:          <td class="LC_left_item"> $old{'id'} </td>
                   2083:          <td class="LC_left_item"> $sid </td>
                   2084:         </tr>
                   2085:         <tr>
                   2086:          <td class="LC_left_item"> <b>$lt{'em'}</b> </td>
                   2087:          <td class="LC_left_item"> $old{'permanentemail'} </td>
                   2088:          <td class="LC_left_item"> $permanentemail </td>
                   2089:         <tr class="LC_odd_row">
                   2090:          <td> <b>$lt{'sec'}</b> </td>
                   2091:          <td> $old{'section'} </td>
                   2092:          <td> $section</td>
                   2093:         </tr>
                   2094:        </table>
                   2095:       </td>
                   2096:      </tr>
                   2097:    </table>
                   2098:    <br />
                   2099:    <table class="LC_nested_outer">
                   2100:      <tr>
                   2101:       <th>$lt{'ri'}</th>
                   2102:      </tr>
                   2103:      <tr>
                   2104:       <td>
                   2105:        <table class="LC_nested">
                   2106:         <tr class="LC_odd_row">
                   2107:          <td class="LC_left_item"><b>$lt{'st'}:</b></td>
                   2108:          <td class="LC_right_item"> $displayable_starttime </td>
                   2109:         </tr>
                   2110:         <tr>
                   2111:          <td class="LC_left_item"><b>$lt{'et'}:</b></td>
                   2112:          <td class="LC_right_item"> $displayable_endtime   </td>
                   2113:         </tr>
                   2114:        </table>
                   2115:       </td>
                   2116:      </tr>
                   2117:     </table>
                   2118:   </td>
                   2119:  </tr>
1.50      matthew  2120: </table>
1.52      matthew  2121: <p>
1.50      matthew  2122: END
1.53      matthew  2123:     #
1.63      matthew  2124:     # Send request(s) to modify data (final undef is for 'desiredhost',
                   2125:     # which is a moot point because the student already has an account.
1.173     raeburn  2126:     my $modify_section_results = 
                   2127:         &Apache::lonuserutils::modifystudent($sdom,$slogin,
                   2128:                                              $env{'request.course.id'},
                   2129:                                              $section,undef);
1.63      matthew  2130:     if ($modify_section_results !~ /^ok/) {
1.174     bisitz   2131:         $r->print(&mt('An error occurred during the attempt to change the section for this student.')."<br />");
1.63      matthew  2132:     }
1.52      matthew  2133:     my $roleresults = &Apache::lonnet::modifystudent
1.53      matthew  2134:         ($sdom,$slogin,$sid,undef,undef,$firstname,$middlename,$lastname,
1.168     raeburn  2135:          $generation,$section,$endtime,$starttime,$env{'form.forceid'},
                   2136:          undef,$permanentemail);
                   2137:     if ($old{'permanentemail'} ne $permanentemail) {
                   2138:         &Apache::loncommon::flush_email_cache($slogin,$sdom);
                   2139:     }
1.53      matthew  2140:     if ($roleresults eq 'refused' ) {
1.94      sakharuk 2141:         $r->print(&mt('Your request to change the role information for this student was refused. You do not appear to have sufficient authority to change student information.'));
1.50      matthew  2142:     } elsif ($roleresults !~ /ok/) {
1.94      sakharuk 2143:         $r->print(&mt('An error occurred during the attempt to change the role information for this student.')."  <br />".
                   2144:                   &mt('The error reported was')." ".
1.50      matthew  2145:                   $roleresults);
1.53      matthew  2146:         &Apache::lonnet::logthis("londropadd:failed attempt to modify student".
1.162     albertel 2147:                                  " data for ".$slogin." : ".$sdom." by ".
                   2148:                                  $env{'user.name'}." : ".$env{'user.domain'}.
1.53      matthew  2149:                                  ":".$roleresults);
1.50      matthew  2150:     } else { # everything is okay!
1.94      sakharuk 2151:         $r->print(&mt('Student information updated successfully.')." <br />".
                   2152:                   &mt('The student must log out and log in again to see these changes.'));
1.50      matthew  2153:     }
1.94      sakharuk 2154:     my $Masd=&mt('Modify another students data');
1.50      matthew  2155:     $r->print(<<END);
1.52      matthew  2156: </p><p>
1.59      matthew  2157: <input type="hidden" name="action" value="modifystudent" />
                   2158: <input type="hidden" name="sortby" value="$sortby" />
                   2159: <input type="hidden" name="Status" value="$status" />
1.94      sakharuk 2160: <a href="javascript:document.studentform.submit();">$Masd</a>
1.50      matthew  2161: END
1.138     albertel 2162:     $r->print(&Apache::loncommon::end_page());
1.50      matthew  2163:     return;
                   2164: }
                   2165: 
                   2166: sub get_enrollment_data {
                   2167:     my ($sname,$sdomain) = @_;
1.127     albertel 2168:     my $courseid = $env{'request.course.id'};
1.151     albertel 2169:     my $cdom = $env{'course.'.$courseid.'.domain'};
                   2170:     my $cnum = $env{'course.'.$courseid.'.num'};
1.50      matthew  2171:     my %roles = &Apache::lonnet::dump('roles',$sdomain,$sname);
                   2172:     my ($tmp) = keys(%roles);
                   2173:     # Bail out if we were unable to get the students roles
1.87      matthew  2174:     return ('error'.$tmp) if ($tmp =~ /^(con_lost|error|no_such_host)/i);
1.50      matthew  2175:     # Go through the roles looking for enrollment in this course
                   2176:     my ($end,$start) = (undef,undef);
                   2177:     my $section = '';
                   2178:     my $count = scalar(keys(%roles));
                   2179:     while (my ($course,$role) = each(%roles)) {
1.150     albertel 2180:         if ($course=~m{^/\Q$cdom\E/\Q$cnum\E/*\s*(\w+)*_st$} ) {
1.50      matthew  2181:             #
                   2182:             # Get active role
                   2183:             $section=$1;
                   2184:             (undef,$end,$start)=split(/\_/,$role);
                   2185:             my $now=time;
                   2186:             my $notactive=0;
                   2187:             if ($start) {
                   2188:                 if ($now<$start) { $notactive=1; }
                   2189:             }
                   2190:             if ($end) {
                   2191:                 if ($now>$end) { $notactive=1; }
                   2192:             } 
                   2193:             unless ($notactive) { return ($start,$end,$section); }
                   2194:         }
                   2195:     }
                   2196:     return ($start,$end,$section);
                   2197: }
                   2198: 
1.56      matthew  2199: 
                   2200: =pod
                   2201: 
1.175   ! jms      2202: =item show_drop_list()
1.56      matthew  2203: 
                   2204: Display a list of students to drop
                   2205: Inputs: 
                   2206: 
                   2207: =over 4
                   2208: 
                   2209: =item $r, Apache request
                   2210: 
                   2211: =item $classlist, hash pointer returned from loncoursedata::get_classlist();
                   2212: 
                   2213: =item $keylist, array pointer returned from loncoursedata::get_classlist() 
                   2214: which describes the order elements are stored in the %$classlist values.
                   2215: 
                   2216: =item $nosort, if true, sorting links are omitted.
                   2217: 
                   2218: =back
                   2219: 
                   2220: =cut
                   2221: 
1.11      www      2222: sub show_drop_list {
1.56      matthew  2223:     my ($r,$classlist,$keylist,$nosort)=@_;
1.127     albertel 2224:     my $cid=$env{'request.course.id'};
                   2225:     if (! exists($env{'form.sortby'})) {
1.59      matthew  2226:         &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                   2227:                                                 ['sortby']);
                   2228:     }
1.127     albertel 2229:     my $sortby = $env{'form.sortby'};
1.142     raeburn  2230:     if ($sortby !~ /^(username|domain|section|groups|fullname|id|start|end)$/) {
1.54      matthew  2231:         $sortby = 'username';
                   2232:     }
1.142     raeburn  2233:     my $cdom = $env{'course.'.$cid.'.domain'};
                   2234:     my $cnum = $env{'course.'.$cid,'.num'};
                   2235:     my ($classgroups) = &Apache::loncoursedata::get_group_memberships(
1.143     raeburn  2236:                                               $classlist,$keylist,$cdom,$cnum);
1.56      matthew  2237:     #
1.54      matthew  2238:     my $action = "drop";
                   2239:     $r->print(<<END);
                   2240: <input type="hidden" name="sortby" value="$sortby" />
                   2241: <input type="hidden" name="action" value="$action" />
1.50      matthew  2242: <input type="hidden" name="state"  value="done" />
1.32      matthew  2243: <script>
1.51      matthew  2244: function checkAll(field) {
1.32      matthew  2245:     for (i = 0; i < field.length; i++)
                   2246:         field[i].checked = true ;
                   2247: }
                   2248: 
1.51      matthew  2249: function uncheckAll(field) {
1.32      matthew  2250:     for (i = 0; i < field.length; i++)
                   2251:         field[i].checked = false ;
                   2252: }
                   2253: </script>
                   2254: <p>
1.26      matthew  2255: <input type="hidden" name="phase" value="four">
1.56      matthew  2256: END
                   2257: 
1.110     matthew  2258: my %lt=&Apache::lonlocal::texthash('usrn'   => "username",
                   2259:                                    'dom'    => "domain",
                   2260:                                    'sn'     => "student name",
                   2261:                                    'sec'    => "section",
                   2262:                                    'start'  => "start date",
                   2263:                                    'end'    => "end date",
1.142     raeburn  2264:                                    'groups' => "active groups",
1.110     matthew  2265:                                    );
1.56      matthew  2266:     if ($nosort) {
1.139     albertel 2267: 	$r->print(&Apache::loncommon::start_data_table());
1.56      matthew  2268:         $r->print(<<END);
                   2269: <tr>
                   2270:     <th>&nbsp;</th>
1.94      sakharuk 2271:     <th>$lt{'usrn'}</th>
                   2272:     <th>$lt{'dom'}</th>
1.56      matthew  2273:     <th>ID</th>
1.94      sakharuk 2274:     <th>$lt{'sn'}</th>
                   2275:     <th>$lt{'sec'}</th>
1.110     matthew  2276:     <th>$lt{'start'}</th>
                   2277:     <th>$lt{'end'}</th>
1.142     raeburn  2278:     <th>$lt{'groups'}</th>
1.56      matthew  2279: </tr>
                   2280: END
                   2281: 
                   2282:     } else  {
1.139     albertel 2283: 	$r->print(&Apache::loncommon::start_data_table());
1.56      matthew  2284:         $r->print(<<END);
1.54      matthew  2285: <tr><th>&nbsp;</th>
                   2286:     <th>
1.94      sakharuk 2287:        <a href="/adm/dropadd?action=$action&sortby=username">$lt{'usrn'}</a>
1.54      matthew  2288:     </th><th>
1.94      sakharuk 2289:        <a href="/adm/dropadd?action=$action&sortby=domain">$lt{'dom'}</a>
1.54      matthew  2290:     </th><th>
                   2291:        <a href="/adm/dropadd?action=$action&sortby=id">ID</a>
                   2292:     </th><th>
1.94      sakharuk 2293:        <a href="/adm/dropadd?action=$action&sortby=fullname">$lt{'sn'}</a>
1.54      matthew  2294:     </th><th>
1.94      sakharuk 2295:        <a href="/adm/dropadd?action=$action&sortby=section">$lt{'sec'}</a>
1.110     matthew  2296:     </th><th>
                   2297:        <a href="/adm/dropadd?action=$action&sortby=start">$lt{'start'}</a>
                   2298:     </th><th>
                   2299:        <a href="/adm/dropadd?action=$action&sortby=end">$lt{'end'}</a>
1.142     raeburn  2300:     </th><th>
                   2301:        <a href="/adm/dropadd?action=$action&sortby=groups">$lt{'groups'}</a>
1.54      matthew  2302:     </th>
                   2303: </tr>
1.26      matthew  2304: END
1.56      matthew  2305:     }
                   2306:     #
                   2307:     # Sort the students
                   2308:     my %index;
                   2309:     my $i;
                   2310:     foreach (@$keylist) {
                   2311:         $index{$_} = $i++;
                   2312:     }
1.142     raeburn  2313:     $index{'groups'} = scalar(@$keylist);
1.56      matthew  2314:     my $index  = $index{$sortby};
                   2315:     my $second = $index{'username'};
                   2316:     my $third  = $index{'domain'};
1.54      matthew  2317:     my @Sorted_Students = sort {
1.56      matthew  2318:         lc($classlist->{$a}->[$index])  cmp lc($classlist->{$b}->[$index])
                   2319:             ||
                   2320:         lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
                   2321:             ||
                   2322:         lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
                   2323:         } (keys(%$classlist));
1.54      matthew  2324:     foreach my $student (@Sorted_Students) {
1.52      matthew  2325:         my $error;
1.110     matthew  2326:         my $sdata = $classlist->{$student};
                   2327:         my $username = $sdata->[$index{'username'}];
                   2328:         my $domain   = $sdata->[$index{'domain'}];
                   2329:         my $section  = $sdata->[$index{'section'}];
                   2330:         my $name     = $sdata->[$index{'fullname'}];
                   2331:         my $id       = $sdata->[$index{'id'}];
                   2332:         my $start    = $sdata->[$index{'start'}];
                   2333:         my $end      = $sdata->[$index{'end'}];
1.142     raeburn  2334:         my $groups = $classgroups->{$student};
                   2335:         my $active_groups;
                   2336:         if (ref($groups->{active}) eq 'HASH') {
                   2337:             $active_groups = join(', ',keys(%{$groups->{'active'}}));
                   2338:         }
1.110     matthew  2339:         if (! defined($start) || $start == 0) {
                   2340:             $start = &mt('none');
                   2341:         } else {
                   2342:             $start = &Apache::lonlocal::locallocaltime($start);
                   2343:         }
                   2344:         if (! defined($end) || $end == 0) {
                   2345:             $end = &mt('none');
                   2346:         } else {
                   2347:             $end = &Apache::lonlocal::locallocaltime($end);
                   2348:         }
                   2349:         my $status   = $sdata->[$index{'status'}];
1.51      matthew  2350:         next if ($status ne 'Active');
                   2351:         #
1.139     albertel 2352:         $r->print(&Apache::loncommon::start_data_table_row());
1.51      matthew  2353:         $r->print(<<"END");
                   2354:     <td><input type="checkbox" name="droplist" value="$student"></td>
                   2355:     <td>$username</td>
                   2356:     <td>$domain</td>
                   2357:     <td>$id</td>
                   2358:     <td>$name</td>
                   2359:     <td>$section</td>
1.110     matthew  2360:     <td>$start</td>
                   2361:     <td>$end</td>
1.142     raeburn  2362:     <td>$active_groups</td>
1.26      matthew  2363: END
1.139     albertel 2364:         $r->print(&Apache::loncommon::end_data_table_row());
1.25      matthew  2365:     }
1.139     albertel 2366:     $r->print(&Apache::loncommon::end_data_table().'<br />');
1.111     matthew  2367:     %lt=&Apache::lonlocal::texthash(
1.94      sakharuk 2368: 	               'dp'   => "Drop Students",
                   2369:                        'ca'   => "check all",
                   2370:                        'ua'   => "uncheck all",
                   2371: 				       );
1.32      matthew  2372:     $r->print(<<"END");
                   2373: </p><p>
1.94      sakharuk 2374: <input type="button" value="$lt{'ca'}" onclick="javascript:checkAll(document.studentform.droplist)"> &nbsp;
                   2375: <input type="button" value="$lt{'ua'}" onclick="javascript:uncheckAll(document.studentform.droplist)"> 
                   2376: <p><input type=submit value="$lt{'dp'}"></p>
1.32      matthew  2377: END
1.51      matthew  2378:     return;
1.10      www      2379: }
                   2380: 
1.175   ! jms      2381: 
        !          2382: =pod 
        !          2383: 
        !          2384: =item print_first_courselist_upload_form()
        !          2385: 
        !          2386:     Print out the initial form to get the courselist file
        !          2387: 
        !          2388: =cut
        !          2389: 
1.48      matthew  2390: sub print_first_courselist_upload_form {
                   2391:     my $r=shift;
1.88      matthew  2392:     my $str;
                   2393:     $str  = '<input type="hidden" name="phase" value="two">';
                   2394:     $str .= '<input type="hidden" name="action" value="upload" />';
                   2395:     $str .= '<input type="hidden"   name="state"  value="got_file" />';
                   2396:     $str .= "<h3>".&mt('Upload a class list')."</h3>\n";
                   2397:     $str .= &Apache::loncommon::upfile_select_html();
                   2398:     $str .= "<p>\n";
                   2399:     $str .= '<input type="submit" name="fileupload" value="'.
                   2400:         &mt('Upload class list').'">'."\n";
1.131     albertel 2401:     $str .= '<label><input type="checkbox" name="noFirstLine" /> '.
                   2402:         &mt('Ignore First Line')."</label></p>\n";
1.88      matthew  2403:     $str .= &Apache::loncommon::help_open_topic("Course_Create_Class_List",
1.92      sakharuk 2404:                          &mt("How do I create a class list from a spreadsheet")).
1.88      matthew  2405:                              "<br />\n";
                   2406:     $str .= &Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
1.92      sakharuk 2407:                            &mt("How do I create a CSV file from a spreadsheet")).
1.88      matthew  2408:                                "<br />\n";
1.138     albertel 2409:     $str .= &Apache::loncommon::end_page();
1.88      matthew  2410:     $r->print($str);
1.48      matthew  2411:     return;
                   2412: }
                   2413: 
1.175   ! jms      2414: 
        !          2415: =pod
        !          2416: 
        !          2417: =item upfile_drop_add()
        !          2418: 
        !          2419:     Drop/Add from uploaded file
        !          2420: 
        !          2421: =cut
        !          2422: 
1.10      www      2423: sub upfile_drop_add {
                   2424:     my $r=shift;
1.24      albertel 2425:     &Apache::loncommon::load_tmp_file($r);
                   2426:     my @studentdata=&Apache::loncommon::upfile_record_sep();
1.127     albertel 2427:     if($env{'form.noFirstLine'}){shift(@studentdata);}
                   2428:     my @keyfields = split(/\,/,$env{'form.keyfields'});
                   2429:     my $cid = $env{'request.course.id'};
1.25      matthew  2430:     my %fields=();
1.127     albertel 2431:     for (my $i=0; $i<=$env{'form.nfields'}; $i++) {
                   2432:         if ($env{'form.upfile_associate'} eq 'reverse') {
                   2433:             if ($env{'form.f'.$i} ne 'none') {
                   2434:                 $fields{$keyfields[$i]}=$env{'form.f'.$i};
1.25      matthew  2435:             }
                   2436:         } else {
1.127     albertel 2437:             $fields{$env{'form.f'.$i}}=$keyfields[$i];
1.25      matthew  2438:         }
                   2439:     }
1.99      matthew  2440:     #
                   2441:     # Store the field choices away
                   2442:     foreach my $field (qw/username names 
                   2443:                        fname mname lname gen id sec ipwd email/) {
1.127     albertel 2444:         $env{'form.'.$field.'_choice'}=$fields{$field};
1.99      matthew  2445:     }
                   2446:     &Apache::loncommon::store_course_settings('enrollment_upload',
                   2447:                                               { 'username_choice' => 'scalar',
                   2448:                                                 'names_choice' => 'scalar',
                   2449:                                                 'fname_choice' => 'scalar',
                   2450:                                                 'mname_choice' => 'scalar',
                   2451:                                                 'lname_choice' => 'scalar',
                   2452:                                                 'gen_choice' => 'scalar',
                   2453:                                                 'id_choice' => 'scalar',
                   2454:                                                 'sec_choice' => 'scalar',
                   2455:                                                 'ipwd_choice' => 'scalar',
                   2456:                                                 'email_choice' => 'scalar' });
                   2457: 
1.26      matthew  2458:     #
1.68      matthew  2459:     my ($startdate,$enddate) = &get_dates_from_form();
1.127     albertel 2460:     if ($env{'form.makedatesdefault'}) {
1.68      matthew  2461:         $r->print(&make_dates_default($startdate,$enddate));
                   2462:     }
1.31      matthew  2463:     # Determine domain and desired host (home server)
1.127     albertel 2464:     my $domain=$env{'form.lcdomain'};
                   2465:     my $desiredhost = $env{'form.lcserver'};
1.31      matthew  2466:     if (lc($desiredhost) eq 'default') {
                   2467:         $desiredhost = undef;
                   2468:     } else {
1.157     albertel 2469:         my %home_servers = &Apache::lonnet::get_servers($domain,'library');
1.31      matthew  2470:         if (! exists($home_servers{$desiredhost})) {
1.88      matthew  2471:             $r->print('<font color="#ff0000">'.&mt('Error').'</font>'.
                   2472:                       &mt('Invalid home server specified'));
1.138     albertel 2473:             $r->print(&Apache::loncommon::end_page());
1.31      matthew  2474:             return;
                   2475:         }
                   2476:     }
1.26      matthew  2477:     # Determine authentication mechanism
                   2478:     my $amode  = '';
                   2479:     my $genpwd = '';
1.127     albertel 2480:     if ($env{'form.login'} eq 'krb') {
1.47      albertel 2481:         $amode='krb';
1.127     albertel 2482: 	$amode.=$env{'form.krbver'};
                   2483:         $genpwd=$env{'form.krbarg'};
                   2484:     } elsif ($env{'form.login'} eq 'int') {
1.25      matthew  2485:         $amode='internal';
1.127     albertel 2486:         if ((defined($env{'form.intarg'})) && ($env{'form.intarg'})) {
                   2487:             $genpwd=$env{'form.intarg'};
1.25      matthew  2488:         }
1.127     albertel 2489:     } elsif ($env{'form.login'} eq 'loc') {
1.25      matthew  2490:         $amode='localauth';
1.127     albertel 2491:         if ((defined($env{'form.locarg'})) && ($env{'form.locarg'})) {
                   2492:             $genpwd=$env{'form.locarg'};
1.79      matthew  2493:         }
                   2494:     }
                   2495:     if ($amode =~ /^krb/) {
                   2496:         if (! defined($genpwd) || $genpwd eq '') {
                   2497:             $r->print('<font color="red" size="+1">'.
1.88      matthew  2498:                       &mt('Unable to enroll students').'</font>  '.
                   2499:                       &mt('No Kerberos domain was specified.').'</p>');
1.79      matthew  2500:             $amode = ''; # This causes the loop below to be skipped
1.25      matthew  2501:         }
                   2502:     }
1.154     raeburn  2503:     if ( $domain eq &LONCAPA::clean_domain($domain)
1.150     albertel 2504: 	&& ($amode ne '')) {
1.26      matthew  2505:         #######################################
                   2506:         ##         Enroll Students           ##
                   2507:         #######################################
1.88      matthew  2508:         $r->print('<h3>'.&mt('Enrolling Students')."</h3>\n<p>\n");
1.25      matthew  2509:         my $count=0;
                   2510:         my $flushc=0;
                   2511:         my %student=();
1.142     raeburn  2512:         # Get information about course groups
1.143     raeburn  2513:         my %curr_groups = &Apache::longroup::coursegroups();
1.26      matthew  2514:         # Get new classlist
1.25      matthew  2515:         foreach (@studentdata) {
                   2516:             my %entries=&Apache::loncommon::record_sep($_);
1.26      matthew  2517:             # Determine student name
1.25      matthew  2518:             unless (($entries{$fields{'username'}} eq '') ||
                   2519:                     (!defined($entries{$fields{'username'}}))) {
1.26      matthew  2520:                 my ($fname, $mname, $lname,$gen) = ('','','','');
1.25      matthew  2521:                 if (defined($fields{'names'})) {
1.26      matthew  2522:                     ($lname,$fname,$mname)=($entries{$fields{'names'}}=~
                   2523:                                             /([^\,]+)\,\s*(\w+)\s*(.*)$/);
1.25      matthew  2524:                 } else {
                   2525:                     if (defined($fields{'fname'})) {
                   2526:                         $fname=$entries{$fields{'fname'}};
                   2527:                     }
                   2528:                     if (defined($fields{'mname'})) {
                   2529:                         $mname=$entries{$fields{'mname'}};
                   2530:                     }
                   2531:                     if (defined($fields{'lname'})) {
                   2532:                         $lname=$entries{$fields{'lname'}};
                   2533:                     }
                   2534:                     if (defined($fields{'gen'})) {
                   2535:                         $gen=$entries{$fields{'gen'}};
                   2536:                     }
                   2537:                 }
1.150     albertel 2538:                 if ($entries{$fields{'username'}}
                   2539: 		    ne &LONCAPA::clean_username($entries{$fields{'username'}})) {
1.88      matthew  2540:                     $r->print('<br />'.
                   2541:       &mt('<b>[_1]</b>: Unacceptable username for user [_2] [_3] [_4] [_5]',
                   2542:           $entries{$fields{'username'}},$fname,$mname,$lname,$gen).
                   2543:                               '</b>');
1.25      matthew  2544:                 } else {
1.26      matthew  2545:                     # determine section number
1.25      matthew  2546:                     my $sec='';
                   2547:                     my $username=$entries{$fields{'username'}};
                   2548:                     if (defined($fields{'sec'})) {
                   2549:                         if (defined($entries{$fields{'sec'}})) {
                   2550:                             $sec=$entries{$fields{'sec'}};
                   2551:                         }
                   2552:                     }
1.80      matthew  2553:                     # remove non alphanumeric values from section
                   2554:                     $sec =~ s/\W//g;
1.142     raeburn  2555:                     if ($sec eq "none" || $sec eq 'all') {
                   2556:                         $r->print('<br />'.
                   2557:       &mt('<b>[_1]</b>: Unable to enroll: section name "[_2]" for user [_3] [_4] [_5] [_6] is a reserved word.',
                   2558:                         $username,$sec,$fname,$mname,$lname,$gen));
                   2559:                         next;
                   2560:                     } elsif (($sec ne '') && (exists($curr_groups{$sec}))) {
                   2561:                         $r->print('<br />'.
                   2562:       &mt('<b>[_1]</b>: Unable to enroll: section name "[_2]" for user [_3] [_4] [_5] [_6] is a course group. Section names and group names must be distinct.',
                   2563:                         $username,$sec,$fname,$mname,$lname,$gen));
                   2564:                         next;
                   2565:                     }
1.26      matthew  2566:                     # determine student id number
1.25      matthew  2567:                     my $id='';
                   2568:                     if (defined($fields{'id'})) {
                   2569:                         if (defined($entries{$fields{'id'}})) {
                   2570:                             $id=$entries{$fields{'id'}};
                   2571:                         }
                   2572:                         $id=~tr/A-Z/a-z/;
                   2573:                     }
1.73      www      2574:                     # determine email address
                   2575:                     my $email='';
                   2576:                     if (defined($fields{'email'})) {
                   2577:                         if (defined($entries{$fields{'email'}})) {
                   2578:                             $email=$entries{$fields{'email'}};
                   2579:                             unless ($email=~/^[^\@]+\@[^\@]+$/) { $email=''; }
                   2580:                         }
                   2581:                     }
1.26      matthew  2582:                     # determine student password
1.25      matthew  2583:                     my $password='';
                   2584:                     if ($genpwd) { 
                   2585:                         $password=$genpwd; 
                   2586:                     } else {
                   2587:                         if (defined($fields{'ipwd'})) {
                   2588:                             if ($entries{$fields{'ipwd'}}) {
                   2589:                                 $password=$entries{$fields{'ipwd'}};
                   2590:                             }
                   2591:                         }
                   2592:                     }
1.56      matthew  2593:                     # Clean up whitespace
                   2594:                     foreach (\$domain,\$username,\$id,\$fname,\$mname,
                   2595:                              \$lname,\$gen,\$sec) {
                   2596:                         $$_ =~ s/(\s+$|^\s+)//g;
                   2597:                     }
1.127     albertel 2598:                     if ($password || $env{'form.login'} eq 'loc') {
1.173     raeburn  2599:                         &Apache::lonuserutils::modifystudent($domain,
                   2600:                                                          $username,$cid,
                   2601:                                                          $sec,$desiredhost);
1.25      matthew  2602:                         my $reply=&Apache::lonnet::modifystudent
                   2603:                             ($domain,$username,$id,$amode,$password,
                   2604:                              $fname,$mname,$lname,$gen,$sec,$enddate,
1.127     albertel 2605:                              $startdate,$env{'form.forceid'},$desiredhost,
1.73      www      2606:                              $email);
1.26      matthew  2607:                         if ($reply ne 'ok') {
1.72      matthew  2608:                             $reply =~ s/^error://;
1.88      matthew  2609:                             $r->print('<br />'.
                   2610:                 &mt('<b>[_1]</b>:  Unable to enroll: [_2]',$username,$reply));
1.10      www      2611:          		} else {
1.7       www      2612:                             $count++; $flushc++;
                   2613:                             $student{$username}=1;
1.6       www      2614:                             $r->print('. ');
1.7       www      2615:                             if ($flushc>15) {
                   2616: 				$r->rflush;
                   2617:                                 $flushc=0;
                   2618:                             }
1.6       www      2619:                         }
1.25      matthew  2620:                     } else {
1.88      matthew  2621:                         $r->print('<br />'.
                   2622:       &mt('<b>[_1]</b>: Unable to enroll.  No password specified.',$username)
                   2623:                                   );
1.25      matthew  2624:                     }
                   2625:                 }
1.26      matthew  2626:             }
                   2627:         } # end of foreach (@studentdata)
1.88      matthew  2628:         $r->print("</p>\n<p>\n".&mt('Processed [_1] student(s).',$count).
                   2629:                   "</p>\n");
                   2630:         $r->print("<p>\n".
                   2631:                   &mt('If active, the new role will be available when the '.
                   2632:                   'students next log in to LON-CAPA.')."</p>\n");
1.26      matthew  2633:         #####################################
                   2634:         #           Drop students           #
                   2635:         #####################################
1.127     albertel 2636:         if ($env{'form.fullup'} eq 'yes') {
1.88      matthew  2637:             $r->print('<h3>'.&mt('Dropping Students')."</h3>\n");
1.26      matthew  2638:             #  Get current classlist
1.56      matthew  2639:             my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
                   2640:             if (! defined($classlist)) {
1.88      matthew  2641:                 $r->print(&mt('There are no students currently enrolled.').
                   2642:                           "\n");
1.56      matthew  2643:             } else {
                   2644:                 # Remove the students we just added from the list of students.
1.25      matthew  2645:                 foreach (@studentdata) {
                   2646:                     my %entries=&Apache::loncommon::record_sep($_);
                   2647:                     unless (($entries{$fields{'username'}} eq '') ||
                   2648:                             (!defined($entries{$fields{'username'}}))) {
1.56      matthew  2649:                         delete($classlist->{$entries{$fields{'username'}}.
1.26      matthew  2650:                                                 ':'.$domain});
1.25      matthew  2651:                     }
                   2652:                 }
1.56      matthew  2653:                 # Print out list of dropped students.
                   2654:                 &show_drop_list($r,$classlist,$keylist,'nosort');
1.25      matthew  2655:             }
                   2656:         }
1.26      matthew  2657:     } # end of unless
1.10      www      2658: }
                   2659: 
1.11      www      2660: # ================================================================== Phase four
                   2661: sub drop_student_list {
                   2662:     my $r=shift;
                   2663:     my $count=0;
1.128     albertel 2664:     my @droplist = &Apache::loncommon::get_env_multiple('form.droplist');
1.35      matthew  2665:     foreach (@droplist) {
1.26      matthew  2666:         my ($uname,$udom)=split(/\:/,$_);
1.56      matthew  2667:         # drop student
1.173     raeburn  2668:         my $result = &Apache::lonuserutils::modifystudent($udom,$uname,
                   2669:                                                 $env{'request.course.id'});
1.37      matthew  2670:         if ($result eq 'ok' || $result eq 'ok:') {
1.88      matthew  2671:             $r->print(&mt('Dropped [_1]',$uname.'@'.$udom).'<br>');
1.59      matthew  2672:             $count++;
1.35      matthew  2673:         } else {
1.88      matthew  2674:             $r->print(
                   2675:           &mt('Error dropping [_1]:[_2]',$uname.'@'.$udom,$result).
1.35      matthew  2676:                       '<br />');
                   2677:         }
1.20      harris41 2678:     }
1.88      matthew  2679:     $r->print('<p><b>'.&mt('Dropped [_1] student(s).',$count).'</b></p>');
                   2680:     $r->print('<p>'.&mt('Re-enrollment will re-activate data.')) if ($count);
1.11      www      2681: }
                   2682: 
1.142     raeburn  2683: sub section_check_js {
                   2684:     my $groupslist;
1.143     raeburn  2685:     my %curr_groups = &Apache::longroup::coursegroups();
1.142     raeburn  2686:     if (%curr_groups) {
                   2687:         $groupslist = join('","',sort(keys(%curr_groups)));
                   2688:     }
                   2689:     return <<"END";
                   2690: function validate(caller) {
                   2691:     var groups = new Array("$groupslist");
                   2692:     var secname = caller.value;
                   2693:     if ((secname == 'all') || (secname == 'none')) {
                   2694:         alert("'"+secname+"' may not be used as the name for a section, as it is a reserved word.\\nPlease choose a different section name.");
                   2695:         return 'error';
                   2696:     }
                   2697:     if (secname != '') {
                   2698:         for (var k=0; k<groups.length; k++) {
                   2699:             if (secname == groups[k]) {
                   2700:                 alert("'"+secname+"' may not be used as the name for a section, as it is the name of a course group.\\nSection names and group names must be distinct. Please choose a different section name.");
                   2701:                 return 'error';
                   2702:             }
                   2703:         }
                   2704:     }
                   2705:     return 'ok';
                   2706: }
                   2707: END
                   2708: }
                   2709: 
1.164     albertel 2710: sub get_permission {
                   2711:     my %permission;
                   2712:     $permission{'view'} = 
                   2713:         &Apache::lonnet::allowed('vcl',$env{'request.course.id'});
                   2714:     if (!$permission{'view'}) {
                   2715: 	my $scope = $env{'request.course.id'}.'/'.$env{'request.course.sec'};
                   2716: 	$permission{'view'} =  &Apache::lonnet::allowed('vcl',$scope);
                   2717: 	if ($permission{'view'}) {
                   2718: 	    $permission{'view_section'} = $env{'request.course.sec'};
                   2719: 	}
                   2720:     }
                   2721: 
                   2722:     $permission{'enrl'} = 
                   2723:         &Apache::lonnet::allowed('cst',$env{'request.course.id'});
                   2724: 
                   2725:     $permission{'grp_view'} =
                   2726:         &Apache::lonnet::allowed('vcg',$env{'request.course.id'});
                   2727:     $permission{'grp_manage'} =
                   2728:         &Apache::lonnet::allowed('mdg',$env{'request.course.id'});
                   2729:     my $allowed = 0;
                   2730:     foreach my $perm (values(%permission)) {
                   2731: 	if ($perm) { $allowed=1; last; }
                   2732:     }
                   2733:     return (\%permission,$allowed);
                   2734: }
                   2735: 
1.50      matthew  2736: =pod
                   2737: 
1.175   ! jms      2738: =item &handler()
1.50      matthew  2739: 
                   2740: The typical handler you see in all these modules.  Takes $r, the
                   2741: http request, as an argument.  
                   2742: 
                   2743: The response to the request is governed by two form variables
                   2744: 
                   2745:  form.action      form.state     response
                   2746:  ---------------------------------------------------
                   2747:  undefined        undefined      print main menu
                   2748:  upload           undefined      print courselist upload menu
                   2749:  upload           got_file       deal with uploaded file,
                   2750:                                  print the upload managing menu
                   2751:  upload           enrolling      enroll students based on upload
                   2752:  drop             undefined      print the classlist ready to drop
                   2753:  drop             done           drop the selected students
1.74      matthew  2754:  enrollstudent    undefined      print student username domain form
                   2755:  enrollstudent    gotusername    print single student enroll menu
1.50      matthew  2756:  enrollstudent    enrolling      enroll student
                   2757:  classlist        undefined      print html classlist
                   2758:  classlist        csv            print csv classlist
                   2759:  modifystudent    undefined      print classlist to select student to modify
                   2760:  modifystudent    selected       print modify student menu
                   2761:  modifystudent    done           make modifications to student record
                   2762: 
                   2763: =cut
                   2764: 
1.10      www      2765: sub handler {
1.26      matthew  2766:     my $r=shift;
                   2767:     if ($r->header_only) {
1.86      www      2768:         &Apache::loncommon::content_type($r,'text/html');
1.26      matthew  2769:         $r->send_http_header;
                   2770:         return OK;
                   2771:     }
1.48      matthew  2772:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.50      matthew  2773:                                             ['action','state']);
1.102     matthew  2774: 
                   2775:     &Apache::lonhtmlcommon::clear_breadcrumbs();
                   2776:     &Apache::lonhtmlcommon::add_breadcrumb
                   2777:         ({href=>"/adm/dropadd",
                   2778:           text=>"Enrollment Manager",
                   2779:           faq=>9,bug=>'Instructor Interface',});
1.26      matthew  2780:     #  Needs to be in a course
1.127     albertel 2781:     if (! ($env{'request.course.fn'})) {
1.121     matthew  2782:         # Not in a course
1.127     albertel 2783:         $env{'user.error.msg'}=
1.132     raeburn  2784:             "/adm/dropadd:cst:0:0:Cannot manage or view course groups, ".
                   2785:                                   "or drop or add students";
1.50      matthew  2786:         return HTTP_NOT_ACCEPTABLE; 
                   2787:     }
                   2788:     #
1.132     raeburn  2789: 
1.164     albertel 2790:     my ($permission,$allowed) = &get_permission();
1.132     raeburn  2791: 
1.164     albertel 2792:     if (!$allowed) {
1.127     albertel 2793:         $env{'user.error.msg'}=
1.164     albertel 2794: 	    "/adm/dropadd:cst:0:0:Cannot manage or view course groups, ".
                   2795: 	                         "or drop or add students";
1.132     raeburn  2796:         return HTTP_NOT_ACCEPTABLE;
1.121     matthew  2797:     }
1.132     raeburn  2798: 
1.121     matthew  2799:     #
1.50      matthew  2800:     # Only output the header information if they did not request csv format
                   2801:     #
1.103     matthew  2802:     # Start page
                   2803:     &Apache::loncommon::content_type($r,'text/html');
                   2804:     $r->send_http_header;
1.50      matthew  2805:     #
                   2806:     # Main switch on form.action and form.state, as appropriate
1.127     albertel 2807:     if (! exists($env{'form.action'})) {
1.166     raeburn  2808:         $r->print(&header());
1.141     albertel 2809:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enrollment Manager'));
1.164     albertel 2810:         my $action = &print_main_menu($r,$permission);
                   2811:     } elsif ($env{'form.action'} eq 'upload' && $permission->{'enrl'}) {
1.166     raeburn  2812:         $r->print(&header());
1.102     matthew  2813:         &Apache::lonhtmlcommon::add_breadcrumb
                   2814:             ({href=>'/adm/dropadd?action=upload&state=',
1.106     matthew  2815:               text=>"Upload Classlist"});
1.141     albertel 2816:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Upload Classlist',
                   2817: 						      'Course_Create_Class_List'));
1.127     albertel 2818:         if (! exists($env{'form.state'})) {
1.50      matthew  2819:             &print_first_courselist_upload_form($r);            
1.127     albertel 2820:         } elsif ($env{'form.state'} eq 'got_file') {
1.50      matthew  2821:             &print_upload_manager_form($r);
1.127     albertel 2822:         } elsif ($env{'form.state'} eq 'enrolling') {
                   2823:             if ($env{'form.datatoken'}) {
1.26      matthew  2824:                 &upfile_drop_add($r);
1.50      matthew  2825:             } else {
                   2826:                 # Hmmm, this is an error
1.26      matthew  2827:             }
1.50      matthew  2828:         } else {
                   2829:             &print_first_courselist_upload_form($r);            
1.26      matthew  2830:         }
1.164     albertel 2831:     } elsif ($env{'form.action'} eq 'drop' && $permission->{'enrl'}) {
1.166     raeburn  2832:         $r->print(&header());
1.102     matthew  2833:         &Apache::lonhtmlcommon::add_breadcrumb
                   2834:             ({href=>'/adm/dropadd?action=drop',
1.106     matthew  2835:               text=>"Drop Students"});
1.141     albertel 2836:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Drop Students',
                   2837: 						      'Course_Drop_Student'));
1.127     albertel 2838:         if (! exists($env{'form.state'})) {
1.51      matthew  2839:             &print_drop_menu($r);
1.127     albertel 2840:         } elsif ($env{'form.state'} eq 'done') {
1.26      matthew  2841:             &drop_student_list($r);
1.50      matthew  2842:         } else {
1.55      matthew  2843:             &print_drop_menu($r);
1.26      matthew  2844:         }
1.164     albertel 2845:     } elsif ($env{'form.action'} eq 'enrollstudent' && $permission->{'enrl'}) {
1.166     raeburn  2846:         my @search = ('srchterm','srchby','srchin','srchtype','srchdomain');
                   2847:         my ($jsback,$elements) = &Apache::loncreateuser::crumb_utilities();
                   2848:         my $jscript = '<script type="text/javascript">'.$jsback.'</script>';
1.172     albertel 2849: 	&Apache::loncreateuser::restore_prev_selections();
                   2850: 	my $srch;
                   2851: 	foreach my $item (@search) {
                   2852: 	    $srch->{$item} = $env{'form.'.$item};
                   2853: 	}
                   2854: 
1.166     raeburn  2855:         if ($env{'form.state'} eq 'gotusername') {
                   2856:             if ($env{'form.phase'} eq 'get_user_info') {
                   2857:                 my ($currstate,$response,$forcenewuser,$results) =
                   2858:                     &Apache::loncreateuser::user_search_result($srch);
1.171     raeburn  2859:                 if ($env{'form.currstate'} eq 'modify') {
                   2860:                     $currstate = $env{'form.currstate'};
                   2861:                 }
1.166     raeburn  2862:                 if ($currstate eq 'select') {
                   2863:                     $r->print(&header());
                   2864:                     &Apache::lonhtmlcommon::add_breadcrumb
                   2865:                         ({href=>"javascript:backPage(document.usersrchform,'','')",
                   2866:                           text=>"Single user search"},
                   2867:                          {href=>"javascript:backPage(document.usersrchform,'get_user_info','select')",
                   2868:                           text=>"Select User",});
                   2869:                     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student',
                   2870:                                                                   'Course_Add_Student'));
                   2871:                     &Apache::loncreateuser::print_user_selection_page($r,
                   2872:                         $response,$srch,$results,'enrollstudent',\@search);
                   2873:                 } elsif ($currstate eq 'modify') {
                   2874:                     my ($ccuname,$ccdomain);
                   2875:                     if (($srch->{'srchby'} eq 'uname') &&
                   2876:                         ($srch->{'srchtype'} eq 'exact')) {
                   2877:                         $ccuname = $srch->{'srchterm'};
                   2878:                         $ccdomain= $srch->{'srchdomain'};
                   2879:                     } else {
                   2880:                         my @matchedunames = keys(%{$results});
                   2881:                         ($ccuname,$ccdomain) = split(/:/,$matchedunames[0]);
                   2882:                     }
                   2883:                     $ccuname =&LONCAPA::clean_username($ccuname);
                   2884:                     $ccdomain=&LONCAPA::clean_domain($ccdomain);
                   2885:                     &print_enroll_single_student_form($r,$jscript,$ccuname,
                   2886:                                                       $ccdomain,$srch,$response);
                   2887:                 } elsif ($currstate eq 'query') {
                   2888:                     $r->print(&header($jscript));
                   2889:                     &Apache::lonhtmlcommon::add_breadcrumb
                   2890:                         ({href=>"javascript:backPage(document.studentform,'','')",
                   2891:                           text=>"Single user search"});
                   2892:                     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student',
                   2893:                                                       'Course_Add_Student'));
                   2894:                     &Apache::loncreateuser::print_user_query_page($r,'enrollstudent');
                   2895:                 } else {
                   2896:                     &get_student_username_domain_form($r,$elements,$response,
                   2897:                                                       $srch,$forcenewuser);
                   2898:                 }
                   2899:             } elsif ($env{'form.phase'} eq 'userpicked') {
                   2900:                 my $ccuname = &LONCAPA::clean_username($env{'form.seluname'});
                   2901:                 my $ccdomain = &LONCAPA::clean_domain($env{'form.seludom'});
                   2902:                 &print_enroll_single_student_form($r,$jscript,$ccuname,
                   2903:                                                   $ccdomain,$srch);
                   2904:             } else {
1.172     albertel 2905:                 &get_student_username_domain_form($r,$elements,undef,$srch);
1.166     raeburn  2906:             }
1.127     albertel 2907:         } elsif ($env{'form.state'} eq 'enrolling') {
1.166     raeburn  2908:             $r->print(&header($jscript));
                   2909:             &Apache::lonhtmlcommon::add_breadcrumb
                   2910:                 ({href=>"javascript:backPage(document.studentform,'','')",
                   2911:                   text=>"Single user search"});
                   2912:             if ($env{'form.prevphase'} eq 'userpicked') {
                   2913:                &Apache::lonhtmlcommon::add_breadcrumb
                   2914:                ({href=>"javascript:backPage(document.studentform,'get_user_info','select')",
                   2915:                  text=>"Select user",});
                   2916:             }
                   2917:             &Apache::lonhtmlcommon::add_breadcrumb
                   2918:                 ({href=>"javascript:backPage(document.studentform,'$env{'form.prevphase'}','modify')",
                   2919:                   text=>"Set enrollment",},
                   2920:                  {href=>"javascript:backPage(document.studentform,$env{'form.phase'},'')",
                   2921:                  text=>"Result",});
                   2922:             $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student',
                   2923:                                                       'Course_Add_Student'));
                   2924:             &enroll_single_student($r,\@search);
1.50      matthew  2925:         } else {
1.172     albertel 2926:             &get_student_username_domain_form($r,$elements,undef,$srch);
1.26      matthew  2927:         }
1.164     albertel 2928:     } elsif ($env{'form.action'} eq 'classlist' && $permission->{'view'}) {
1.167     raeburn  2929:         $r->print(&header());
1.102     matthew  2930:         &Apache::lonhtmlcommon::add_breadcrumb
                   2931:             ({href=>'/adm/dropadd?action=classlist',
1.106     matthew  2932:               text=>"View Classlist"});
1.141     albertel 2933:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('View Classlist',
                   2934: 						      'Course_View_Class_List'));
1.127     albertel 2935:         if (! exists($env{'form.state'})) {
1.164     albertel 2936:             &print_html_classlist($r,undef,$permission);
1.127     albertel 2937:         } elsif ($env{'form.state'} eq 'csv') {
1.164     albertel 2938:             &print_html_classlist($r,'csv',$permission);
1.127     albertel 2939:         } elsif ($env{'form.state'} eq 'excel') {
1.164     albertel 2940:             &print_html_classlist($r,'excel',$permission);
1.50      matthew  2941:         } else {
1.164     albertel 2942:             &print_html_classlist($r,undef,$permission);
1.50      matthew  2943:         }
1.164     albertel 2944:     } elsif ($env{'form.action'} eq 'modifystudent' && $permission->{'enrl'}) {
1.167     raeburn  2945:         $r->print(&header());
1.102     matthew  2946:         &Apache::lonhtmlcommon::add_breadcrumb
                   2947:             ({href=>'/adm/dropadd?action=modifystudent',
1.106     matthew  2948:               text=>"Modify Student Data"});
1.141     albertel 2949:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Modify Student Data',
                   2950: 						      'Course_Modify_Student_Data'));
1.127     albertel 2951:         if (! exists($env{'form.state'})) {
1.164     albertel 2952:             &print_html_classlist($r,undef,$permission);
1.127     albertel 2953:         } elsif ($env{'form.state'} eq 'selected') {
1.50      matthew  2954:             &print_modify_student_form($r);
1.127     albertel 2955:         } elsif ($env{'form.state'} eq 'done') {
1.50      matthew  2956:             &modify_single_student($r);
                   2957:         } else {
1.164     albertel 2958:             &print_html_classlist($r,undef,$permission);
1.50      matthew  2959:         }        
                   2960:     } else {
                   2961:         # We should not end up here, but I guess it is possible
                   2962:         &Apache::lonnet::logthis("Undetermined state in londropadd.pm.  ".
1.127     albertel 2963:                                  "form.action = ".$env{'form.action'}.
1.50      matthew  2964:                                  "Someone should fix this.");
1.167     raeburn  2965:         $r->print(&header());
1.141     albertel 2966:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enrollment Manager'));
1.164     albertel 2967:         &print_main_menu($r,$permission);
1.50      matthew  2968:     }
                   2969:     #
                   2970:     # Finish up
1.138     albertel 2971:     $r->print('</form>'.&Apache::loncommon::end_page());
1.26      matthew  2972:     return OK;
1.1       www      2973: }
                   2974: 
1.50      matthew  2975: 
1.1       www      2976: 1;
                   2977: __END__
1.50      matthew  2978: 
1.175   ! jms      2979: =pod
1.1       www      2980: 
1.175   ! jms      2981: =back
        !          2982: 
        !          2983: =cut

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