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

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

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