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

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

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