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

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

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