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

1.1       www         1: # The LearningOnline Network with CAPA
                      2: # Handler to drop and add students in courses 
                      3: #
1.135   ! albertel    4: # $Id: londropadd.pm,v 1.134 2006/02/07 05:08:32 raeburn 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'}) {
1.135   ! albertel 1343:             my %photo_options = &Apache::lonlocal::texthash(
1.134     raeburn  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'}.
1.135   ! albertel 1497: 			 '.internal.showphotos'}) {
1.134     raeburn  1498:                 if ($displayphotos eq 'on') {
1.135   ! albertel 1499:                     my $imgurl = 
        !          1500: 			&Apache::lonnet::retrievestudentphoto($domain,
        !          1501: 							      $username,'gif',
        !          1502: 							      'thumbnail');
1.134     raeburn  1503:                 
                   1504:                     $r->print('    <td align="right"><a href="javascript:photowindow('."'".&Apache::lonnet::studentphoto($domain,$username,'jpg')."'".')"><img src="'.$imgurl.'" border="1"></a></td>');
                   1505:                 } else {
                   1506:                     $r->print('    <td>&nbsp;</td>  ');
                   1507:                 }
                   1508:             }
                   1509:             $r->print('  </tr>  ');
1.51      matthew  1510:         } elsif ($mode eq 'csv') {
1.103     matthew  1511:             next if (! defined($CSVfile));
1.51      matthew  1512:             # no need to bother with $linkto
1.114     raeburn  1513:             if (! defined($start) || $start == 0) {
                   1514:                 $start = &mt('none');
                   1515:             } else {
                   1516:                 $start = &Apache::lonlocal::locallocaltime($start);
                   1517:             }
                   1518:             if (! defined($end) || $end == 0) {
                   1519:                 $end = &mt('none');
                   1520:             } else {
                   1521:                 $end = &Apache::lonlocal::locallocaltime($end);
                   1522:             }
1.51      matthew  1523:             my @line = ();
1.110     matthew  1524:             foreach ($username,$domain,$id,$name,$section,$start,$end) {
1.51      matthew  1525:                 push @line,&Apache::loncommon::csv_translate($_);
1.58      matthew  1526:             }
                   1527:             if ($statusmode eq 'Any') {
                   1528:                 push @line,&Apache::loncommon::csv_translate($status);
1.41      matthew  1529:             }
1.103     matthew  1530:             print $CSVfile '"'.join('","',@line).'"'."\n";
1.60      matthew  1531:         } elsif ($mode eq 'excel') {
1.110     matthew  1532:             $excel_sheet->write($row,0,[$username,$domain,$id,
                   1533:                                           $name,$section]);
                   1534:             my $col = 5;
                   1535:             foreach my $time ($start,$end) {
1.129     matthew  1536:                 if (defined($time) && $time != 0) {
                   1537:                     $excel_sheet->write($row,$col++,
1.110     matthew  1538:                                    &Apache::lonstathelpers::calc_serial($time),
                   1539:                                     $format->{'date'});
1.129     matthew  1540:                 } else {
                   1541:                     $excel_sheet->write($row,$col++,'none');
                   1542:                 }                    
1.110     matthew  1543:             }
                   1544:             $excel_sheet->write($row,$col++,$status);
                   1545:             $row++;
1.40      matthew  1546:         }
                   1547:     }
1.114     raeburn  1548:     if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') {
1.60      matthew  1549:         $r->print('</table><br>');
                   1550:     } elsif ($mode eq 'excel') {
                   1551:         $excel_workbook->close();
                   1552:         $r->print('<p><a href="'.$excel_filename.'">'.
1.94      sakharuk 1553:                   &mt('Your Excel spreadsheet').'</a> '.&mt('is ready for download').'.</p>'."\n");
1.103     matthew  1554:     } elsif ($mode eq 'csv') {
                   1555:         close($CSVfile);
                   1556:         $r->print('<a href="'.$CSVfilename.'">'.
                   1557:                   &mt('Your CSV file').'</a> is ready for download.'.
                   1558:                   "\n");
                   1559:         $r->rflush();
1.60      matthew  1560:     }
1.114     raeburn  1561:     if ($mode eq 'autoenroll') {
1.115     raeburn  1562:         return ($studentcount,$autocount,$manualcount,$lockcount,$unlockcount);
1.114     raeburn  1563:     }
1.115     raeburn  1564:     return;
1.40      matthew  1565: }
                   1566: 
1.50      matthew  1567: 
                   1568: #
                   1569: # print out form for modification of a single students data
                   1570: #
                   1571: sub print_modify_student_form {
                   1572:     my $r = shift();
                   1573:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.59      matthew  1574:                                             ['sdom','sname']);    
1.127     albertel 1575:     my $sname  = $env{'form.sname'};
                   1576:     my $sdom   = $env{'form.sdom'};
                   1577:     my $sortby = $env{'form.sortby'};
1.50      matthew  1578:     # determine the students name information
                   1579:     my %info=&Apache::lonnet::get('environment',
                   1580:                                   ['firstname','middlename',
1.52      matthew  1581:                                    'lastname','generation','id'],
1.50      matthew  1582:                                   $sdom, $sname);
                   1583:     my ($tmp) = keys(%info);
                   1584:     if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.94      sakharuk 1585:         $r->print('<font color="#ff0000" size="+2">'.&mt('Error').'</font>'.
1.50      matthew  1586:                   '<p>'.
1.94      sakharuk 1587:                   &mt('Unable to retrieve environment data for').' '.$sname.
                   1588:                   &mt('in domain').' '.$sdom.'</p><p>'.
                   1589:                   &mt('Please contact your LON-CAPA administrator regarding this situation.').'</p></body></html>');
1.50      matthew  1590:         return;
                   1591:     }
                   1592:     # determine the students starting and ending times and section
                   1593:     my ($starttime,$endtime,$section) = &get_enrollment_data($sname,$sdom);
1.87      matthew  1594:     if ($starttime =~ /^error/) {
1.94      sakharuk 1595:         $r->print('<h2>'&mt('Error').'</h2>');
1.87      matthew  1596:         $r->print('<p>'.$starttime.'</p>');
                   1597:         return;
                   1598:     }
1.101     matthew  1599:     #
1.50      matthew  1600:     # Deal with date forms
1.101     matthew  1601:     my $current_date_description = '';
                   1602:     my $textdate = '';
                   1603: 
                   1604:     if (! defined($starttime) || $starttime == 0) {
                   1605:         $current_date_description = &mt('Current Starting Date: not set').
                   1606:             '<br />';
                   1607:     } else {
                   1608:         $current_date_description = 
                   1609:             &mt('Current Starting Date: [_1]',
                   1610:                 &Apache::lonlocal::locallocaltime($starttime)).'<br />';
                   1611:     }
                   1612:     if (! defined($endtime) || $endtime == 0) {
                   1613:         $current_date_description.= &mt('Current Ending Date: not set').
                   1614:             '<br />';
                   1615:     } else {
                   1616:         $current_date_description.= 
                   1617:             &mt('Current Ending Date: [_1]',
                   1618:                 &Apache::lonlocal::locallocaltime($endtime)).'<br />';
                   1619: 
                   1620:     }
1.68      matthew  1621:     my $date_table = &date_setting_table($starttime,$endtime);
1.59      matthew  1622:     #
1.127     albertel 1623:     if (! exists($env{'form.Status'}) || 
                   1624:         $env{'form.Status'} !~ /^(Any|Expired|Active)$/) {
                   1625:         $env{'form.Status'} = 'crap';
1.59      matthew  1626:     }
1.94      sakharuk 1627:     # Make sure student is enrolled in course
                   1628:     my %lt=&Apache::lonlocal::texthash(
                   1629: 	           'mef'   => "Modify Enrollment for",
                   1630:                    'odcc'  => "Only domain coordinators can change a users password.",
                   1631:                    'sn'    => "Student Name",
                   1632:                    'fn'    => "First",
                   1633:                    'mn'    => "Middle",
                   1634:                    'ln'    => "Last",
                   1635:                    'gen'   => "Generation",
                   1636:                    'sid'   => "Student ID",
                   1637:                    'disn'  => "Disable ID/Student Number Safeguard and Force Change of Conflicting IDs (only do if you know what you are doing)",
                   1638:                    'sec'   => "Section",
                   1639:                    'sm'    => "Submit Modifications",
                   1640: 				       );
1.50      matthew  1641:     $r->print(<<END);
1.52      matthew  1642: <p>
                   1643: <font size="+1">
1.94      sakharuk 1644: $lt{'odcc'}
1.52      matthew  1645: </font>
                   1646: </p>
1.50      matthew  1647: <input type="hidden" name="slogin"  value="$sname"  />
                   1648: <input type="hidden" name="sdomain" value="$sdom" />
                   1649: <input type="hidden" name="action"  value="modifystudent" />
1.53      matthew  1650: <input type="hidden" name="state"   value="done" />
                   1651: <input type="hidden" name="sortby"  value="$sortby" />
1.127     albertel 1652: <input type="hidden" name="Status"  value="$env{'form.Status'}" />
1.94      sakharuk 1653: <h2>$lt{'mef'} $info{'firstname'} $info{'middlename'} 
1.50      matthew  1654: $info{'lastname'} $info{'generation'}, $sname\@$sdom</h2>
                   1655: <p>
1.94      sakharuk 1656: <b>$lt{'sn'}</b>
1.50      matthew  1657: <table>
1.94      sakharuk 1658: <tr><th>$lt{'fn'}</th><th>$lt{'mn'}</th><th>$lt{'ln'}</th><th>$lt{'gen'}</th></tr>
1.50      matthew  1659: <tr><td>
                   1660: <input type="text" name="firstname"  value="$info{'firstname'}"  /></td><td>
                   1661: <input type="text" name="middlename" value="$info{'middlename'}" /></td><td>
                   1662: <input type="text" name="lastname"   value="$info{'lastname'}"   /></td><td>
                   1663: <input type="text" name="generation" value="$info{'generation'}" /></td></tr>
                   1664: </table>
                   1665: </p><p>
1.94      sakharuk 1666: <b>$lt{'sid'}</b>: <input type="text" name="id" value="$info{'id'}" size="12"/>
1.52      matthew  1667: </p><p>
1.131     albertel 1668: <label>
1.53      matthew  1669: <input type="checkbox" name="forceid" > 
1.94      sakharuk 1670: $lt{'disn'}
1.131     albertel 1671: </label>
1.53      matthew  1672: </p><p>
1.101     matthew  1673: <b>$lt{'sec'}</b>: <input type="text" name="section" value="$section" size="14"/>
1.50      matthew  1674: </p>
1.101     matthew  1675: <p>$current_date_description</p>
1.68      matthew  1676: <p>$date_table</p>
1.94      sakharuk 1677: <input type="submit" value="$lt{'sm'}" />
1.50      matthew  1678: </body></html>
                   1679: END
                   1680:     return;
                   1681: }
                   1682: 
                   1683: #
                   1684: # modify a single students section 
                   1685: #
                   1686: sub modify_single_student {
                   1687:     my $r = shift;
1.68      matthew  1688:     #
1.80      matthew  1689:     # Remove non alphanumeric values from the section
1.127     albertel 1690:     $env{'form.section'} =~ s/\W//g;
1.77      matthew  1691:     #
1.68      matthew  1692:     # Do the date defaults first
                   1693:     my ($starttime,$endtime) = &get_dates_from_form();
1.127     albertel 1694:     if ($env{'form.makedatesdefault'}) {
1.68      matthew  1695:         $r->print(&make_dates_default($starttime,$endtime));
                   1696:     }
1.59      matthew  1697:     # Get the 'sortby' and 'Status' variables so the user goes back to their
                   1698:     # previous screen
1.127     albertel 1699:     my $sortby = $env{'form.sortby'};
                   1700:     my $status = $env{'form.Status'};
1.53      matthew  1701:     #
                   1702:     # We always need this information
1.127     albertel 1703:     my $slogin     = $env{'form.slogin'};
                   1704:     my $sdom       = $env{'form.sdomain'};
1.53      matthew  1705:     #
                   1706:     # Get the old data
                   1707:     my %old=&Apache::lonnet::get('environment',
                   1708:                                  ['firstname','middlename',
                   1709:                                   'lastname','generation','id'],
                   1710:                                  $sdom, $slogin);
1.59      matthew  1711:     $old{'section'} = &Apache::lonnet::getsection($sdom,$slogin,
1.127     albertel 1712:                                                   $env{'request.course.id'});
1.53      matthew  1713:     my ($tmp) = keys(%old);
                   1714:     if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.94      sakharuk 1715:         $r->print(&mt('There was an error determining the environment values for')." $slogin \@ $sdom.");
1.53      matthew  1716:         return;
                   1717:     }
                   1718:     undef $tmp;
                   1719:     #
                   1720:     # Get the new data
1.127     albertel 1721:     my $firstname  = $env{'form.firstname'};
                   1722:     my $middlename = $env{'form.middlename'};
                   1723:     my $lastname   = $env{'form.lastname'};
                   1724:     my $generation = $env{'form.generation'};
                   1725:     my $section    = $env{'form.section'};
                   1726:     my $courseid   = $env{'request.course.id'};
                   1727:     my $sid        = $env{'form.id'};
1.50      matthew  1728:     my $displayable_starttime = localtime($starttime);
                   1729:     my $displayable_endtime   = localtime($endtime);
1.53      matthew  1730:     # 
                   1731:     # check for forceid override
1.63      matthew  1732:     if ((defined($old{'id'})) && ($old{'id'} ne '') && 
1.127     albertel 1733:         ($sid ne $old{'id'}) && (! exists($env{'form.forceid'}))) {
1.94      sakharuk 1734:         $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  1735:         $sid = $old{'id'};
                   1736:     }
                   1737:     #
1.50      matthew  1738:     # talk to the user about what we are going to do
1.94      sakharuk 1739:     my %lt=&Apache::lonlocal::texthash(
                   1740: 	           'mdu'   => "Modifying data for user",
                   1741:                    'si'    => "Student Information",
                   1742:                    'fd'    => "Field",
                   1743:                    'ov'    => "Old Value",
                   1744:                    'nv'    => "New Value",
                   1745:                    'fn'    => "First name",
                   1746:                    'mn'    => "Middle name",
                   1747:                    'ln'    => "Last name",
                   1748:                    'gen'   => "Generation",
                   1749:                    'sec'   => "Section",
                   1750:                    'ri'    => "Role Information",
                   1751:                    'st'    => "Start Time",
                   1752:                    'et'    => "End Time",
                   1753: 				       );
1.50      matthew  1754:     $r->print(<<END);
1.94      sakharuk 1755:     <h2>$lt{'mdu'} $slogin \@ $sdom </h2>
                   1756: <h3>$lt{'si'}</h3>
1.53      matthew  1757: <table rules="rows" border="1" cellpadding="3" >
                   1758: <tr>
1.94      sakharuk 1759:     <th> $lt{'fd'} </th>
                   1760:     <th> $lt{'ov'} </th>
                   1761:     <th> $lt{'nv'} </th>
1.53      matthew  1762: </tr>
                   1763: <tr>
1.94      sakharuk 1764:     <td> <b>$lt{'fn'}</b> </td>
1.53      matthew  1765:     <td> $old{'firstname'} </td>
                   1766:     <td> $firstname </td>
                   1767: </tr><tr>
1.94      sakharuk 1768:     <td> <b>$lt{'mn'}</b> </td>
1.53      matthew  1769:     <td> $old{'middlename'} </td>
                   1770:     <td> $middlename </td>
                   1771: </tr><tr>
1.94      sakharuk 1772:     <td> <b>$lt{'ln'}</b> </td>
1.53      matthew  1773:     <td> $old{'lastname'} </td>
                   1774:     <td> $lastname </td>
                   1775: </tr><tr>
1.94      sakharuk 1776:     <td> <b>$lt{'gen'}</b> </td>
1.53      matthew  1777:     <td> $old{'generation'} </td>
                   1778:     <td> $generation </td>
                   1779: </tr><tr>
                   1780:     <td> <b>ID</b> </td>
                   1781:     <td> $old{'id'} </td>
                   1782:     <td> $sid </td>
1.59      matthew  1783: </tr><tr>
1.94      sakharuk 1784:     <td> <b>$lt{'sec'}</b> </td>
1.59      matthew  1785:     <td> $old{'section'} </td>
                   1786:     <td> $section</td>
1.53      matthew  1787: </tr>
1.50      matthew  1788: </table>
1.94      sakharuk 1789: <h3>$lt{'ri'}</h3>
1.50      matthew  1790: <table>
1.94      sakharuk 1791: <tr><td align="right"><b>$lt{'st'}:</b></td><td> $displayable_starttime </td></tr>
                   1792: <tr><td align="right"><b>$lt{'et'}:</b></td><td> $displayable_endtime   </td></tr>
1.50      matthew  1793: </table>
1.52      matthew  1794: <p>
1.50      matthew  1795: END
1.53      matthew  1796:     #
1.63      matthew  1797:     # Send request(s) to modify data (final undef is for 'desiredhost',
                   1798:     # which is a moot point because the student already has an account.
                   1799:     my $modify_section_results = &modifystudent($sdom,$slogin,
1.127     albertel 1800:                                                 $env{'request.course.id'},
1.63      matthew  1801:                                                 $section,undef);
                   1802:     if ($modify_section_results !~ /^ok/) {
1.94      sakharuk 1803:         $r->print(&mt('An error occured during the attempt to change the section for this student.')."<br />");
1.63      matthew  1804:     }
1.52      matthew  1805:     my $roleresults = &Apache::lonnet::modifystudent
1.53      matthew  1806:         ($sdom,$slogin,$sid,undef,undef,$firstname,$middlename,$lastname,
1.127     albertel 1807:          $generation,$section,$endtime,$starttime,$env{'form.forceid'});
1.53      matthew  1808:     if ($roleresults eq 'refused' ) {
1.94      sakharuk 1809:         $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  1810:     } elsif ($roleresults !~ /ok/) {
1.94      sakharuk 1811:         $r->print(&mt('An error occurred during the attempt to change the role information for this student.')."  <br />".
                   1812:                   &mt('The error reported was')." ".
1.50      matthew  1813:                   $roleresults);
1.53      matthew  1814:         &Apache::lonnet::logthis("londropadd:failed attempt to modify student".
                   1815:                                  " data for ".$slogin." \@ ".$sdom." by ".
1.127     albertel 1816:                                  $env{'user.name'}." \@ ".$env{'user.domain'}.
1.53      matthew  1817:                                  ":".$roleresults);
1.50      matthew  1818:     } else { # everything is okay!
1.94      sakharuk 1819:         $r->print(&mt('Student information updated successfully.')." <br />".
                   1820:                   &mt('The student must log out and log in again to see these changes.'));
1.50      matthew  1821:     }
1.94      sakharuk 1822:     my $Masd=&mt('Modify another students data');
1.50      matthew  1823:     $r->print(<<END);
1.52      matthew  1824: </p><p>
1.59      matthew  1825: <input type="hidden" name="action" value="modifystudent" />
                   1826: <input type="hidden" name="sortby" value="$sortby" />
                   1827: <input type="hidden" name="Status" value="$status" />
1.94      sakharuk 1828: <a href="javascript:document.studentform.submit();">$Masd</a>
1.50      matthew  1829: </body></html>
                   1830: END
                   1831:     return;
                   1832: }
                   1833: 
                   1834: sub get_enrollment_data {
                   1835:     my ($sname,$sdomain) = @_;
1.127     albertel 1836:     my $courseid = $env{'request.course.id'};
1.50      matthew  1837:     $courseid =~ s:_:/:g;
                   1838:     my %roles = &Apache::lonnet::dump('roles',$sdomain,$sname);
                   1839:     my ($tmp) = keys(%roles);
                   1840:     # Bail out if we were unable to get the students roles
1.87      matthew  1841:     return ('error'.$tmp) if ($tmp =~ /^(con_lost|error|no_such_host)/i);
1.50      matthew  1842:     # Go through the roles looking for enrollment in this course
                   1843:     my ($end,$start) = (undef,undef);
                   1844:     my $section = '';
                   1845:     my $count = scalar(keys(%roles));
                   1846:     while (my ($course,$role) = each(%roles)) {
                   1847:         if ($course=~ /^\/$courseid\/*\s*(\w+)*_st$/ ) {
                   1848:             #
                   1849:             # Get active role
                   1850:             $section=$1;
                   1851:             (undef,$end,$start)=split(/\_/,$role);
                   1852:             my $now=time;
                   1853:             my $notactive=0;
                   1854:             if ($start) {
                   1855:                 if ($now<$start) { $notactive=1; }
                   1856:             }
                   1857:             if ($end) {
                   1858:                 if ($now>$end) { $notactive=1; }
                   1859:             } 
                   1860:             unless ($notactive) { return ($start,$end,$section); }
                   1861:         }
                   1862:     }
                   1863:     return ($start,$end,$section);
                   1864: }
                   1865: 
1.56      matthew  1866: #################################################
                   1867: #################################################
                   1868: 
                   1869: =pod
                   1870: 
                   1871: =item show_drop_list
                   1872: 
                   1873: Display a list of students to drop
                   1874: Inputs: 
                   1875: 
                   1876: =over 4
                   1877: 
                   1878: =item $r, Apache request
                   1879: 
                   1880: =item $classlist, hash pointer returned from loncoursedata::get_classlist();
                   1881: 
                   1882: =item $keylist, array pointer returned from loncoursedata::get_classlist() 
                   1883: which describes the order elements are stored in the %$classlist values.
                   1884: 
                   1885: =item $nosort, if true, sorting links are omitted.
                   1886: 
                   1887: =back
                   1888: 
                   1889: =cut
                   1890: 
                   1891: #################################################
                   1892: #################################################
1.11      www      1893: sub show_drop_list {
1.56      matthew  1894:     my ($r,$classlist,$keylist,$nosort)=@_;
1.127     albertel 1895:     my $cid=$env{'request.course.id'};
                   1896:     if (! exists($env{'form.sortby'})) {
1.59      matthew  1897:         &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                   1898:                                                 ['sortby']);
                   1899:     }
1.127     albertel 1900:     my $sortby = $env{'form.sortby'};
1.110     matthew  1901:     if ($sortby !~ /^(username|domain|section|fullname|id|start|end)$/) {
1.54      matthew  1902:         $sortby = 'username';
                   1903:     }
1.56      matthew  1904:     #
1.54      matthew  1905:     my $action = "drop";
                   1906:     $r->print(<<END);
                   1907: <input type="hidden" name="sortby" value="$sortby" />
                   1908: <input type="hidden" name="action" value="$action" />
1.50      matthew  1909: <input type="hidden" name="state"  value="done" />
1.32      matthew  1910: <script>
1.51      matthew  1911: function checkAll(field) {
1.32      matthew  1912:     for (i = 0; i < field.length; i++)
                   1913:         field[i].checked = true ;
                   1914: }
                   1915: 
1.51      matthew  1916: function uncheckAll(field) {
1.32      matthew  1917:     for (i = 0; i < field.length; i++)
                   1918:         field[i].checked = false ;
                   1919: }
                   1920: </script>
                   1921: <p>
1.26      matthew  1922: <input type="hidden" name="phase" value="four">
1.56      matthew  1923: END
                   1924: 
1.110     matthew  1925: my %lt=&Apache::lonlocal::texthash('usrn'   => "username",
                   1926:                                    'dom'    => "domain",
                   1927:                                    'sn'     => "student name",
                   1928:                                    'sec'    => "section",
                   1929:                                    'start'  => "start date",
                   1930:                                    'end'    => "end date",
                   1931:                                    );
1.56      matthew  1932:     if ($nosort) {
                   1933:         $r->print(<<END);
                   1934: <table border=2>
                   1935: <tr>
                   1936:     <th>&nbsp;</th>
1.94      sakharuk 1937:     <th>$lt{'usrn'}</th>
                   1938:     <th>$lt{'dom'}</th>
1.56      matthew  1939:     <th>ID</th>
1.94      sakharuk 1940:     <th>$lt{'sn'}</th>
                   1941:     <th>$lt{'sec'}</th>
1.110     matthew  1942:     <th>$lt{'start'}</th>
                   1943:     <th>$lt{'end'}</th>
1.56      matthew  1944: </tr>
                   1945: END
                   1946: 
                   1947:     } else  {
                   1948:         $r->print(<<END);
1.26      matthew  1949: <table border=2>
1.54      matthew  1950: <tr><th>&nbsp;</th>
                   1951:     <th>
1.94      sakharuk 1952:        <a href="/adm/dropadd?action=$action&sortby=username">$lt{'usrn'}</a>
1.54      matthew  1953:     </th><th>
1.94      sakharuk 1954:        <a href="/adm/dropadd?action=$action&sortby=domain">$lt{'dom'}</a>
1.54      matthew  1955:     </th><th>
                   1956:        <a href="/adm/dropadd?action=$action&sortby=id">ID</a>
                   1957:     </th><th>
1.94      sakharuk 1958:        <a href="/adm/dropadd?action=$action&sortby=fullname">$lt{'sn'}</a>
1.54      matthew  1959:     </th><th>
1.94      sakharuk 1960:        <a href="/adm/dropadd?action=$action&sortby=section">$lt{'sec'}</a>
1.110     matthew  1961:     </th><th>
                   1962:        <a href="/adm/dropadd?action=$action&sortby=start">$lt{'start'}</a>
                   1963:     </th><th>
                   1964:        <a href="/adm/dropadd?action=$action&sortby=end">$lt{'end'}</a>
1.54      matthew  1965:     </th>
                   1966: </tr>
1.26      matthew  1967: END
1.56      matthew  1968:     }
                   1969:     #
                   1970:     # Sort the students
                   1971:     my %index;
                   1972:     my $i;
                   1973:     foreach (@$keylist) {
                   1974:         $index{$_} = $i++;
                   1975:     }
                   1976:     my $index  = $index{$sortby};
                   1977:     my $second = $index{'username'};
                   1978:     my $third  = $index{'domain'};
1.54      matthew  1979:     my @Sorted_Students = sort {
1.56      matthew  1980:         lc($classlist->{$a}->[$index])  cmp lc($classlist->{$b}->[$index])
                   1981:             ||
                   1982:         lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
                   1983:             ||
                   1984:         lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
                   1985:         } (keys(%$classlist));
1.54      matthew  1986:     foreach my $student (@Sorted_Students) {
1.52      matthew  1987:         my $error;
1.110     matthew  1988:         my $sdata = $classlist->{$student};
                   1989:         my $username = $sdata->[$index{'username'}];
                   1990:         my $domain   = $sdata->[$index{'domain'}];
                   1991:         my $section  = $sdata->[$index{'section'}];
                   1992:         my $name     = $sdata->[$index{'fullname'}];
                   1993:         my $id       = $sdata->[$index{'id'}];
                   1994:         my $start    = $sdata->[$index{'start'}];
                   1995:         my $end      = $sdata->[$index{'end'}];
                   1996:         if (! defined($start) || $start == 0) {
                   1997:             $start = &mt('none');
                   1998:         } else {
                   1999:             $start = &Apache::lonlocal::locallocaltime($start);
                   2000:         }
                   2001:         if (! defined($end) || $end == 0) {
                   2002:             $end = &mt('none');
                   2003:         } else {
                   2004:             $end = &Apache::lonlocal::locallocaltime($end);
                   2005:         }
                   2006:         my $status   = $sdata->[$index{'status'}];
1.51      matthew  2007:         next if ($status ne 'Active');
                   2008:         #
                   2009:         $r->print(<<"END");
1.26      matthew  2010: <tr>
1.51      matthew  2011:     <td><input type="checkbox" name="droplist" value="$student"></td>
                   2012:     <td>$username</td>
                   2013:     <td>$domain</td>
                   2014:     <td>$id</td>
                   2015:     <td>$name</td>
                   2016:     <td>$section</td>
1.110     matthew  2017:     <td>$start</td>
                   2018:     <td>$end</td>
1.26      matthew  2019: </tr>
                   2020: END
1.25      matthew  2021:     }
                   2022:     $r->print('</table><br>');
1.111     matthew  2023:     %lt=&Apache::lonlocal::texthash(
1.94      sakharuk 2024: 	               'dp'   => "Drop Students",
                   2025:                        'ca'   => "check all",
                   2026:                        'ua'   => "uncheck all",
                   2027: 				       );
1.32      matthew  2028:     $r->print(<<"END");
                   2029: </p><p>
1.94      sakharuk 2030: <input type="button" value="$lt{'ca'}" onclick="javascript:checkAll(document.studentform.droplist)"> &nbsp;
                   2031: <input type="button" value="$lt{'ua'}" onclick="javascript:uncheckAll(document.studentform.droplist)"> 
                   2032: <p><input type=submit value="$lt{'dp'}"></p>
1.32      matthew  2033: END
1.51      matthew  2034:     return;
1.10      www      2035: }
                   2036: 
1.48      matthew  2037: #
                   2038: # Print out the initial form to get the courselist file
                   2039: #
                   2040: sub print_first_courselist_upload_form {
                   2041:     my $r=shift;
1.88      matthew  2042:     my $str;
                   2043:     $str  = '<input type="hidden" name="phase" value="two">';
                   2044:     $str .= '<input type="hidden" name="action" value="upload" />';
                   2045:     $str .= '<input type="hidden"   name="state"  value="got_file" />';
                   2046:     $str .= "<h3>".&mt('Upload a class list')."</h3>\n";
                   2047:     $str .= &Apache::loncommon::upfile_select_html();
                   2048:     $str .= "<p>\n";
                   2049:     $str .= '<input type="submit" name="fileupload" value="'.
                   2050:         &mt('Upload class list').'">'."\n";
1.131     albertel 2051:     $str .= '<label><input type="checkbox" name="noFirstLine" /> '.
                   2052:         &mt('Ignore First Line')."</label></p>\n";
1.88      matthew  2053:     $str .= &Apache::loncommon::help_open_topic("Course_Create_Class_List",
1.92      sakharuk 2054:                          &mt("How do I create a class list from a spreadsheet")).
1.88      matthew  2055:                              "<br />\n";
                   2056:     $str .= &Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
1.92      sakharuk 2057:                            &mt("How do I create a CSV file from a spreadsheet")).
1.88      matthew  2058:                                "<br />\n";
                   2059:     $str .= "</body>\n</html>\n";
                   2060:     $r->print($str);
1.48      matthew  2061:     return;
                   2062: }
                   2063: 
1.10      www      2064: # ================================================= Drop/Add from uploaded file
                   2065: sub upfile_drop_add {
                   2066:     my $r=shift;
1.24      albertel 2067:     &Apache::loncommon::load_tmp_file($r);
                   2068:     my @studentdata=&Apache::loncommon::upfile_record_sep();
1.127     albertel 2069:     if($env{'form.noFirstLine'}){shift(@studentdata);}
                   2070:     my @keyfields = split(/\,/,$env{'form.keyfields'});
                   2071:     my $cid = $env{'request.course.id'};
1.25      matthew  2072:     my %fields=();
1.127     albertel 2073:     for (my $i=0; $i<=$env{'form.nfields'}; $i++) {
                   2074:         if ($env{'form.upfile_associate'} eq 'reverse') {
                   2075:             if ($env{'form.f'.$i} ne 'none') {
                   2076:                 $fields{$keyfields[$i]}=$env{'form.f'.$i};
1.25      matthew  2077:             }
                   2078:         } else {
1.127     albertel 2079:             $fields{$env{'form.f'.$i}}=$keyfields[$i];
1.25      matthew  2080:         }
                   2081:     }
1.99      matthew  2082:     #
                   2083:     # Store the field choices away
                   2084:     foreach my $field (qw/username names 
                   2085:                        fname mname lname gen id sec ipwd email/) {
1.127     albertel 2086:         $env{'form.'.$field.'_choice'}=$fields{$field};
1.99      matthew  2087:     }
                   2088:     &Apache::loncommon::store_course_settings('enrollment_upload',
                   2089:                                               { 'username_choice' => 'scalar',
                   2090:                                                 'names_choice' => 'scalar',
                   2091:                                                 'fname_choice' => 'scalar',
                   2092:                                                 'mname_choice' => 'scalar',
                   2093:                                                 'lname_choice' => 'scalar',
                   2094:                                                 'gen_choice' => 'scalar',
                   2095:                                                 'id_choice' => 'scalar',
                   2096:                                                 'sec_choice' => 'scalar',
                   2097:                                                 'ipwd_choice' => 'scalar',
                   2098:                                                 'email_choice' => 'scalar' });
                   2099: 
1.26      matthew  2100:     #
1.68      matthew  2101:     my ($startdate,$enddate) = &get_dates_from_form();
1.127     albertel 2102:     if ($env{'form.makedatesdefault'}) {
1.68      matthew  2103:         $r->print(&make_dates_default($startdate,$enddate));
                   2104:     }
1.31      matthew  2105:     # Determine domain and desired host (home server)
1.127     albertel 2106:     my $domain=$env{'form.lcdomain'};
                   2107:     my $desiredhost = $env{'form.lcserver'};
1.31      matthew  2108:     if (lc($desiredhost) eq 'default') {
                   2109:         $desiredhost = undef;
                   2110:     } else {
1.45      matthew  2111:         my %home_servers = &Apache::loncommon::get_library_servers($domain);
1.31      matthew  2112:         if (! exists($home_servers{$desiredhost})) {
1.88      matthew  2113:             $r->print('<font color="#ff0000">'.&mt('Error').'</font>'.
                   2114:                       &mt('Invalid home server specified'));
                   2115:             $r->print("</body>\n</html>\n");
1.31      matthew  2116:             return;
                   2117:         }
                   2118:     }
1.26      matthew  2119:     # Determine authentication mechanism
                   2120:     my $amode  = '';
                   2121:     my $genpwd = '';
1.127     albertel 2122:     if ($env{'form.login'} eq 'krb') {
1.47      albertel 2123:         $amode='krb';
1.127     albertel 2124: 	$amode.=$env{'form.krbver'};
                   2125:         $genpwd=$env{'form.krbarg'};
                   2126:     } elsif ($env{'form.login'} eq 'int') {
1.25      matthew  2127:         $amode='internal';
1.127     albertel 2128:         if ((defined($env{'form.intarg'})) && ($env{'form.intarg'})) {
                   2129:             $genpwd=$env{'form.intarg'};
1.25      matthew  2130:         }
1.127     albertel 2131:     } elsif ($env{'form.login'} eq 'loc') {
1.25      matthew  2132:         $amode='localauth';
1.127     albertel 2133:         if ((defined($env{'form.locarg'})) && ($env{'form.locarg'})) {
                   2134:             $genpwd=$env{'form.locarg'};
1.79      matthew  2135:         }
                   2136:     }
                   2137:     if ($amode =~ /^krb/) {
                   2138:         if (! defined($genpwd) || $genpwd eq '') {
                   2139:             $r->print('<font color="red" size="+1">'.
1.88      matthew  2140:                       &mt('Unable to enroll students').'</font>  '.
                   2141:                       &mt('No Kerberos domain was specified.').'</p>');
1.79      matthew  2142:             $amode = ''; # This causes the loop below to be skipped
1.25      matthew  2143:         }
                   2144:     }
                   2145:     unless (($domain=~/\W/) || ($amode eq '')) {
1.26      matthew  2146:         #######################################
                   2147:         ##         Enroll Students           ##
                   2148:         #######################################
1.88      matthew  2149:         $r->print('<h3>'.&mt('Enrolling Students')."</h3>\n<p>\n");
1.25      matthew  2150:         my $count=0;
                   2151:         my $flushc=0;
                   2152:         my %student=();
1.26      matthew  2153:         # Get new classlist
1.25      matthew  2154:         foreach (@studentdata) {
                   2155:             my %entries=&Apache::loncommon::record_sep($_);
1.26      matthew  2156:             # Determine student name
1.25      matthew  2157:             unless (($entries{$fields{'username'}} eq '') ||
                   2158:                     (!defined($entries{$fields{'username'}}))) {
1.26      matthew  2159:                 my ($fname, $mname, $lname,$gen) = ('','','','');
1.25      matthew  2160:                 if (defined($fields{'names'})) {
1.26      matthew  2161:                     ($lname,$fname,$mname)=($entries{$fields{'names'}}=~
                   2162:                                             /([^\,]+)\,\s*(\w+)\s*(.*)$/);
1.25      matthew  2163:                 } else {
                   2164:                     if (defined($fields{'fname'})) {
                   2165:                         $fname=$entries{$fields{'fname'}};
                   2166:                     }
                   2167:                     if (defined($fields{'mname'})) {
                   2168:                         $mname=$entries{$fields{'mname'}};
                   2169:                     }
                   2170:                     if (defined($fields{'lname'})) {
                   2171:                         $lname=$entries{$fields{'lname'}};
                   2172:                     }
                   2173:                     if (defined($fields{'gen'})) {
                   2174:                         $gen=$entries{$fields{'gen'}};
                   2175:                     }
                   2176:                 }
                   2177:                 if ($entries{$fields{'username'}}=~/\W/) {
1.88      matthew  2178:                     $r->print('<br />'.
                   2179:       &mt('<b>[_1]</b>: Unacceptable username for user [_2] [_3] [_4] [_5]',
                   2180:           $entries{$fields{'username'}},$fname,$mname,$lname,$gen).
                   2181:                               '</b>');
1.25      matthew  2182:                 } else {
1.26      matthew  2183:                     # determine section number
1.25      matthew  2184:                     my $sec='';
                   2185:                     my $username=$entries{$fields{'username'}};
                   2186:                     if (defined($fields{'sec'})) {
                   2187:                         if (defined($entries{$fields{'sec'}})) {
                   2188:                             $sec=$entries{$fields{'sec'}};
                   2189:                         }
                   2190:                     }
1.80      matthew  2191:                     # remove non alphanumeric values from section
                   2192:                     $sec =~ s/\W//g;
1.26      matthew  2193:                     # determine student id number
1.25      matthew  2194:                     my $id='';
                   2195:                     if (defined($fields{'id'})) {
                   2196:                         if (defined($entries{$fields{'id'}})) {
                   2197:                             $id=$entries{$fields{'id'}};
                   2198:                         }
                   2199:                         $id=~tr/A-Z/a-z/;
                   2200:                     }
1.73      www      2201:                     # determine email address
                   2202:                     my $email='';
                   2203:                     if (defined($fields{'email'})) {
                   2204:                         if (defined($entries{$fields{'email'}})) {
                   2205:                             $email=$entries{$fields{'email'}};
                   2206:                             unless ($email=~/^[^\@]+\@[^\@]+$/) { $email=''; }
                   2207:                         }
                   2208:                     }
1.26      matthew  2209:                     # determine student password
1.25      matthew  2210:                     my $password='';
                   2211:                     if ($genpwd) { 
                   2212:                         $password=$genpwd; 
                   2213:                     } else {
                   2214:                         if (defined($fields{'ipwd'})) {
                   2215:                             if ($entries{$fields{'ipwd'}}) {
                   2216:                                 $password=$entries{$fields{'ipwd'}};
                   2217:                             }
                   2218:                         }
                   2219:                     }
1.56      matthew  2220:                     # Clean up whitespace
                   2221:                     foreach (\$domain,\$username,\$id,\$fname,\$mname,
                   2222:                              \$lname,\$gen,\$sec) {
                   2223:                         $$_ =~ s/(\s+$|^\s+)//g;
                   2224:                     }
1.127     albertel 2225:                     if ($password || $env{'form.login'} eq 'loc') {
1.33      matthew  2226:                         &modifystudent($domain,$username,$cid,$sec,
                   2227:                                        $desiredhost);
1.25      matthew  2228:                         my $reply=&Apache::lonnet::modifystudent
                   2229:                             ($domain,$username,$id,$amode,$password,
                   2230:                              $fname,$mname,$lname,$gen,$sec,$enddate,
1.127     albertel 2231:                              $startdate,$env{'form.forceid'},$desiredhost,
1.73      www      2232:                              $email);
1.26      matthew  2233:                         if ($reply ne 'ok') {
1.72      matthew  2234:                             $reply =~ s/^error://;
1.88      matthew  2235:                             $r->print('<br />'.
                   2236:                 &mt('<b>[_1]</b>:  Unable to enroll: [_2]',$username,$reply));
1.10      www      2237:          		} else {
1.7       www      2238:                             $count++; $flushc++;
                   2239:                             $student{$username}=1;
1.6       www      2240:                             $r->print('. ');
1.7       www      2241:                             if ($flushc>15) {
                   2242: 				$r->rflush;
                   2243:                                 $flushc=0;
                   2244:                             }
1.6       www      2245:                         }
1.25      matthew  2246:                     } else {
1.88      matthew  2247:                         $r->print('<br />'.
                   2248:       &mt('<b>[_1]</b>: Unable to enroll.  No password specified.',$username)
                   2249:                                   );
1.25      matthew  2250:                     }
                   2251:                 }
1.26      matthew  2252:             }
                   2253:         } # end of foreach (@studentdata)
1.88      matthew  2254:         $r->print("</p>\n<p>\n".&mt('Processed [_1] student(s).',$count).
                   2255:                   "</p>\n");
                   2256:         $r->print("<p>\n".
                   2257:                   &mt('If active, the new role will be available when the '.
                   2258:                   'students next log in to LON-CAPA.')."</p>\n");
1.26      matthew  2259:         #####################################
                   2260:         #           Drop students           #
                   2261:         #####################################
1.127     albertel 2262:         if ($env{'form.fullup'} eq 'yes') {
1.88      matthew  2263:             $r->print('<h3>'.&mt('Dropping Students')."</h3>\n");
1.26      matthew  2264:             #  Get current classlist
1.56      matthew  2265:             my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
                   2266:             if (! defined($classlist)) {
1.88      matthew  2267:                 $r->print(&mt('There are no students currently enrolled.').
                   2268:                           "\n");
1.56      matthew  2269:             } else {
                   2270:                 # Remove the students we just added from the list of students.
1.25      matthew  2271:                 foreach (@studentdata) {
                   2272:                     my %entries=&Apache::loncommon::record_sep($_);
                   2273:                     unless (($entries{$fields{'username'}} eq '') ||
                   2274:                             (!defined($entries{$fields{'username'}}))) {
1.56      matthew  2275:                         delete($classlist->{$entries{$fields{'username'}}.
1.26      matthew  2276:                                                 ':'.$domain});
1.25      matthew  2277:                     }
                   2278:                 }
1.56      matthew  2279:                 # Print out list of dropped students.
                   2280:                 &show_drop_list($r,$classlist,$keylist,'nosort');
1.25      matthew  2281:             }
                   2282:         }
1.26      matthew  2283:     } # end of unless
1.10      www      2284: }
                   2285: 
1.11      www      2286: # ================================================================== Phase four
                   2287: sub drop_student_list {
                   2288:     my $r=shift;
                   2289:     my $count=0;
1.128     albertel 2290:     my @droplist = &Apache::loncommon::get_env_multiple('form.droplist');
1.35      matthew  2291:     foreach (@droplist) {
1.26      matthew  2292:         my ($uname,$udom)=split(/\:/,$_);
1.56      matthew  2293:         # drop student
1.127     albertel 2294:         my $result = &modifystudent($udom,$uname,$env{'request.course.id'});
1.37      matthew  2295:         if ($result eq 'ok' || $result eq 'ok:') {
1.88      matthew  2296:             $r->print(&mt('Dropped [_1]',$uname.'@'.$udom).'<br>');
1.59      matthew  2297:             $count++;
1.35      matthew  2298:         } else {
1.88      matthew  2299:             $r->print(
                   2300:           &mt('Error dropping [_1]:[_2]',$uname.'@'.$udom,$result).
1.35      matthew  2301:                       '<br />');
                   2302:         }
1.20      harris41 2303:     }
1.88      matthew  2304:     $r->print('<p><b>'.&mt('Dropped [_1] student(s).',$count).'</b></p>');
                   2305:     $r->print('<p>'.&mt('Re-enrollment will re-activate data.')) if ($count);
1.11      www      2306: }
                   2307: 
1.50      matthew  2308: ###################################################################
                   2309: ###################################################################
                   2310: 
                   2311: =pod
                   2312: 
                   2313: =item &handler
                   2314: 
                   2315: The typical handler you see in all these modules.  Takes $r, the
                   2316: http request, as an argument.  
                   2317: 
                   2318: The response to the request is governed by two form variables
                   2319: 
                   2320:  form.action      form.state     response
                   2321:  ---------------------------------------------------
                   2322:  undefined        undefined      print main menu
                   2323:  upload           undefined      print courselist upload menu
                   2324:  upload           got_file       deal with uploaded file,
                   2325:                                  print the upload managing menu
                   2326:  upload           enrolling      enroll students based on upload
                   2327:  drop             undefined      print the classlist ready to drop
                   2328:  drop             done           drop the selected students
1.74      matthew  2329:  enrollstudent    undefined      print student username domain form
                   2330:  enrollstudent    gotusername    print single student enroll menu
1.50      matthew  2331:  enrollstudent    enrolling      enroll student
                   2332:  classlist        undefined      print html classlist
                   2333:  classlist        csv            print csv classlist
                   2334:  modifystudent    undefined      print classlist to select student to modify
                   2335:  modifystudent    selected       print modify student menu
                   2336:  modifystudent    done           make modifications to student record
                   2337: 
                   2338: =cut
                   2339: 
                   2340: ###################################################################
                   2341: ###################################################################
1.10      www      2342: sub handler {
1.26      matthew  2343:     my $r=shift;
                   2344:     if ($r->header_only) {
1.86      www      2345:         &Apache::loncommon::content_type($r,'text/html');
1.26      matthew  2346:         $r->send_http_header;
                   2347:         return OK;
                   2348:     }
1.48      matthew  2349:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.50      matthew  2350:                                             ['action','state']);
1.102     matthew  2351: 
                   2352:     &Apache::lonhtmlcommon::clear_breadcrumbs();
                   2353:     &Apache::lonhtmlcommon::add_breadcrumb
                   2354:         ({href=>"/adm/dropadd",
                   2355:           text=>"Enrollment Manager",
                   2356:           faq=>9,bug=>'Instructor Interface',});
1.26      matthew  2357:     #  Needs to be in a course
1.127     albertel 2358:     if (! ($env{'request.course.fn'})) {
1.121     matthew  2359:         # Not in a course
1.127     albertel 2360:         $env{'user.error.msg'}=
1.132     raeburn  2361:             "/adm/dropadd:cst:0:0:Cannot manage or view course groups, ".
                   2362:                                   "or drop or add students";
1.50      matthew  2363:         return HTTP_NOT_ACCEPTABLE; 
                   2364:     }
                   2365:     #
1.121     matthew  2366:     my $view_permission = 
1.127     albertel 2367:         &Apache::lonnet::allowed('vcl',$env{'request.course.id'});
1.121     matthew  2368:     my $enrl_permission = 
1.127     albertel 2369:         &Apache::lonnet::allowed('cst',$env{'request.course.id'});
1.132     raeburn  2370: 
                   2371:     my $grp_view_permission =
                   2372:         &Apache::lonnet::allowed('vcg',$env{'request.course.id'});
                   2373:     my $grp_manage_permission =
                   2374:         &Apache::lonnet::allowed('mdg',$env{'request.course.id'});
                   2375: 
                   2376: 
                   2377:     if (! $grp_view_permission && ! $grp_manage_permission && 
                   2378:                                   ! $view_permission && ! $enrl_permission) {
1.127     albertel 2379:         $env{'user.error.msg'}=
1.132     raeburn  2380:      "/adm/coursegroups:cst:0:0:Cannot manage or view course groups, ".
                   2381:                                  "or drop or add students";
                   2382:         return HTTP_NOT_ACCEPTABLE;
1.121     matthew  2383:     }
1.132     raeburn  2384: 
1.121     matthew  2385:     #
1.50      matthew  2386:     # Only output the header information if they did not request csv format
                   2387:     #
1.103     matthew  2388:     # Start page
                   2389:     &Apache::loncommon::content_type($r,'text/html');
                   2390:     $r->send_http_header;
                   2391:     $r->print(&header());
1.50      matthew  2392:     #
                   2393:     # Main switch on form.action and form.state, as appropriate
1.127     albertel 2394:     if (! exists($env{'form.action'})) {
1.102     matthew  2395:         $r->print(&Apache::lonhtmlcommon::breadcrumbs
                   2396:                   (undef,'Enrollment Manager'));
1.132     raeburn  2397:         &print_main_menu($r,$enrl_permission,$view_permission,$grp_manage_permission,
                   2398:                          $grp_view_permission);
1.127     albertel 2399:     } elsif ($env{'form.action'} eq 'upload' && $enrl_permission) {
1.102     matthew  2400:         &Apache::lonhtmlcommon::add_breadcrumb
                   2401:             ({href=>'/adm/dropadd?action=upload&state=',
1.106     matthew  2402:               text=>"Upload Classlist"});
1.102     matthew  2403:         $r->print(&Apache::lonhtmlcommon::breadcrumbs
1.117     albertel 2404:                   (undef,'Upload Classlist','Course_Create_Class_List'));
1.127     albertel 2405:         if (! exists($env{'form.state'})) {
1.50      matthew  2406:             &print_first_courselist_upload_form($r);            
1.127     albertel 2407:         } elsif ($env{'form.state'} eq 'got_file') {
1.50      matthew  2408:             &print_upload_manager_form($r);
1.127     albertel 2409:         } elsif ($env{'form.state'} eq 'enrolling') {
                   2410:             if ($env{'form.datatoken'}) {
1.26      matthew  2411:                 &upfile_drop_add($r);
1.50      matthew  2412:             } else {
                   2413:                 # Hmmm, this is an error
1.26      matthew  2414:             }
1.50      matthew  2415:         } else {
                   2416:             &print_first_courselist_upload_form($r);            
1.26      matthew  2417:         }
1.127     albertel 2418:     } elsif ($env{'form.action'} eq 'drop' && $enrl_permission) {
1.102     matthew  2419:         &Apache::lonhtmlcommon::add_breadcrumb
                   2420:             ({href=>'/adm/dropadd?action=drop',
1.106     matthew  2421:               text=>"Drop Students"});
1.102     matthew  2422:         $r->print(&Apache::lonhtmlcommon::breadcrumbs
1.117     albertel 2423:                   (undef,'Drop Students','Course_Drop_Student'));
1.127     albertel 2424:         if (! exists($env{'form.state'})) {
1.51      matthew  2425:             &print_drop_menu($r);
1.127     albertel 2426:         } elsif ($env{'form.state'} eq 'done') {
1.26      matthew  2427:             &drop_student_list($r);
1.50      matthew  2428:         } else {
1.55      matthew  2429:             &print_drop_menu($r);
1.26      matthew  2430:         }
1.127     albertel 2431:     } elsif ($env{'form.action'} eq 'enrollstudent' && $enrl_permission) {
1.102     matthew  2432:         &Apache::lonhtmlcommon::add_breadcrumb
                   2433:             ({href=>'/adm/dropadd?action=enrollstudent',
1.106     matthew  2434:               text=>"Enroll Student"});
1.102     matthew  2435:         $r->print(&Apache::lonhtmlcommon::breadcrumbs
1.117     albertel 2436:                   (undef,'Enroll Student','Course_Add_Student'));
1.127     albertel 2437:         if (! exists($env{'form.state'})) {
1.74      matthew  2438:             &get_student_username_domain_form($r);
1.127     albertel 2439:         } elsif ($env{'form.state'} eq 'gotusername') {
1.50      matthew  2440:             &print_enroll_single_student_form($r);
1.127     albertel 2441:         } elsif ($env{'form.state'} eq 'enrolling') {
1.26      matthew  2442:             &enroll_single_student($r);
1.50      matthew  2443:         } else {
1.74      matthew  2444:             &get_student_username_domain_form($r);
1.26      matthew  2445:         }
1.127     albertel 2446:     } elsif ($env{'form.action'} eq 'classlist' && $view_permission) {
1.102     matthew  2447:         &Apache::lonhtmlcommon::add_breadcrumb
                   2448:             ({href=>'/adm/dropadd?action=classlist',
1.106     matthew  2449:               text=>"View Classlist"});
1.102     matthew  2450:         $r->print(&Apache::lonhtmlcommon::breadcrumbs
1.117     albertel 2451:                   (undef,'View Classlist','Course_View_Class_List'));
1.127     albertel 2452:         if (! exists($env{'form.state'})) {
1.103     matthew  2453:             &print_html_classlist($r,undef);
1.127     albertel 2454:         } elsif ($env{'form.state'} eq 'csv') {
1.103     matthew  2455:             &print_html_classlist($r,'csv');
1.127     albertel 2456:         } elsif ($env{'form.state'} eq 'excel') {
1.103     matthew  2457:             &print_html_classlist($r,'excel');
1.50      matthew  2458:         } else {
1.103     matthew  2459:             &print_html_classlist($r,undef);
1.50      matthew  2460:         }
1.127     albertel 2461:     } elsif ($env{'form.action'} eq 'modifystudent' && $enrl_permission) {
1.102     matthew  2462:         &Apache::lonhtmlcommon::add_breadcrumb
                   2463:             ({href=>'/adm/dropadd?action=modifystudent',
1.106     matthew  2464:               text=>"Modify Student Data"});
1.102     matthew  2465:         $r->print(&Apache::lonhtmlcommon::breadcrumbs
1.117     albertel 2466:                   (undef,'Modify Student Data','Course_Modify_Student_Data'));
1.127     albertel 2467:         if (! exists($env{'form.state'})) {
1.50      matthew  2468:             &print_html_classlist($r);
1.127     albertel 2469:         } elsif ($env{'form.state'} eq 'selected') {
1.50      matthew  2470:             &print_modify_student_form($r);
1.127     albertel 2471:         } elsif ($env{'form.state'} eq 'done') {
1.50      matthew  2472:             &modify_single_student($r);
                   2473:         } else {
                   2474:             &print_html_classlist($r);
                   2475:         }        
                   2476:     } else {
                   2477:         # We should not end up here, but I guess it is possible
                   2478:         &Apache::lonnet::logthis("Undetermined state in londropadd.pm.  ".
1.127     albertel 2479:                                  "form.action = ".$env{'form.action'}.
1.50      matthew  2480:                                  "Someone should fix this.");
1.102     matthew  2481:         $r->print(&Apache::lonhtmlcommon::breadcrumbs
                   2482:                   (undef,'Enrollment Manager'));
1.121     matthew  2483:         &print_main_menu($r,$enrl_permission,$view_permission);
1.50      matthew  2484:     }
                   2485:     #
                   2486:     # Finish up
1.103     matthew  2487:     $r->print('</form></body></html>');
1.26      matthew  2488:     return OK;
1.1       www      2489: }
                   2490: 
1.50      matthew  2491: ###################################################################
                   2492: ###################################################################
                   2493: 
1.1       www      2494: 1;
                   2495: __END__
1.50      matthew  2496: 
1.1       www      2497: 

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